From 6e04fa60f637f98e6f6218455780fecf914c24bc Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 00:12:57 +0800 Subject: [PATCH 01/59] =?UTF-8?q?docs(06):=20=E7=99=BB=E8=AE=B0=E3=80=8C?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=B3=A8=E9=87=8A=E7=A6=81=E7=94=A8=E8=AF=8D?= =?UTF-8?q?=E6=B8=85=E6=89=AB=E6=89=B9=E3=80=8D=E6=9D=A1=E7=9B=AE=EF=BC=88?= =?UTF-8?q?=E5=B7=A5=E7=A8=8B=E7=9B=B4=E5=85=A5=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 来源=会话提及,设计面=工程直入——凭 2026-10-19 全量扫描的可复核实测读数 (范围 game/ 195 文件;口径=剔除对照性/历史文本行)跳过设计轨。 现状登记三组事实: - 确定违规(术语表「退役词对照」在册,落于代码注释面):板级 26/门票 38/ 正主 12(含误报 1)/落籍 10(含历史注记 1,不追改) - 含「雷」字面 16 处,其中 3 处为玩家可见文案,违反术语表「对外命名纪律」 - 已核实清零(迭代 31 成果):金币/插旗/标旗/雷格/惩罚格/旗 均为 0 根因:迭代 31 卡① 完成判据 V4 只覆盖四词,排雷/雷族未入判据;且机检闸 doc_term_audit.py 的 DEFAULT_DIRS 只含 design/gdd,代码注释面从未进闸。 上游依据=2026-10-19 用户裁:完美排雷全库统一换代为「完美封印」(含代码 内部注释),据此推翻 需求卡片-凭证件裁削批:108「内部开发用语按 v3.15 纪律 保留」半句,该卡片条款订正归文档轨批。 --- design/gdd/06-待办清单.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index c45e60cd..f7e7c8d2 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -675,3 +675,19 @@ **归属**:①`奇物.md` §1.1/§2.2/v2.2 行(已订正写入文档);②`奇物.md` §1.3(:121/:223/:229)与 `02-系统清单.md:49`(待裁) **状态**:已写入(design/gdd/systems/冒险循环/奇物.md v3.19——第①项专长凭证归类订正)+待裁决(第②项资源判据句,心智模型未对齐,不列候选不提前处置) + +--- + +#### 代码注释禁用词清扫批——退役词换代+完美排雷统一为完美封印(2026-10-20 登记,来源=会话提及,设计面=工程直入) + +**现状**:2026-10-19 全量扫描 `game/`(195 个文件:.gd/.tres/.md/.json/.sh/.txt)的可复核实测读数,口径=剔除含对照性/历史信号的行后计「疑似现行残留」。 +**确定违规**(术语表「退役词对照」在册,落于代码注释面)=`板级` 26 处/`门票` 38 处/`正主` 12 处(含 `tests/unit/battle_settlement/damage_math_test.gd:36`「正主角池」误报 1 处)/`落籍` 10 处(含 `data/tables/enemy.tres:653` 带 commit 号的历史注记 1 处,不追改)。 +**含「雷」字面**(违反术语表「对外命名纪律」——「雷」及相关字面禁入对外命名,适用范围含 UI 文案)=`完美排雷` 16 处,其中 **3 处为玩家可见文案**:`core/battle_orchestrator.gd:925` `"完美排雷!清图奖励 ×2"`、`presentation/views/board_fx_view.gd:102` `_show_banner("完美排雷 ×2")`、`presentation/views/battle_log_view.gd:194` `"(本板完美排雷已破——归因此封印)"`(末条 `design/qa/文案审查报告-2026-10-18.md:150` 已判病句,至今未修)。 +**根因**:迭代 31 卡① 完成判据 V4 只覆盖「金币/插旗/雷格/惩罚格」四词(+旗族),`排雷`/`雷`族未入完成判据;且机检闸 `tools/doc_term_audit.py` 的 `DEFAULT_DIRS = ["design/gdd"]`,**代码注释面从未进闸**——不清根则同类残留持续复发。 +**裁定(2026-10-19 用户)**:完美排雷**全库统一**换代为「完美封印」,含代码内部注释。本裁**推翻** `需求卡片-凭证件裁削批`:108「内部开发用语按 v3.15 纪律保留」半句,该卡片条款订正归**文档轨批**,代码批照本裁执行。 +**移交(不属本批)**:`game/data/tables/shop.tres:86` display_name「奇物门票」、`game/presentation/curio_interact_controller.gd:165-166`「开一次奇物三选一」——两处属 奇物/专长 归类表述,与 06「2026-10-18 冒记案遗留待裁两项」第①项同源,交文档侧先定性,定后另走传导批。 +**不做(待用户另裁)**:术语表 A 表词(`不得` 14/`报错` 18/`对标` 1/`若干` 1/`buff` 22——后者绝大多数是标识符与数据键)、doc-conventions 第 4 节流程动词(`收口` 128/`随批` 20/`台账` 17/`对拍` 16/`在飞` 10/`落文` 2)、简明技术中文(STC)通用禁用词(`缺省` 105/`情况` 26/`入参|出参` 23/`比较|较为|相对` 22 等)。 + +**归属**:game/ 代码与数据表(代码域,走独立 worktree 批;并行避让——`changelog-retire-20261019` 在盘未合回且正在改 `AGENTS.md` 与 `design/dev/code-conventions.md`,本批禁碰这两个文件,S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`) + +**状态**:待写卡 From 3e3bc136f9e6137bf719c5ec5af43bbe4107c3b5 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 00:45:43 +0800 Subject: [PATCH 02/59] =?UTF-8?q?docs(card):=20=E9=9C=80=E6=B1=82=E5=8D=A1?= =?UTF-8?q?=E7=89=87=C2=B7=E4=BB=A3=E7=A0=81=E6=B3=A8=E9=87=8A=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E8=AF=8D=E6=B8=85=E6=89=AB=E6=89=B9=20v1.0=20?= =?UTF-8?q?=EF=BC=8B=2006=20=E6=9D=A1=E7=9B=AE=E6=8E=A8=E8=BF=9B=E3=80=8C?= =?UTF-8?q?=E5=B7=B2=E5=86=99=E5=8D=A1=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 卡片落 design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md,六需求点: N1 完美排雷→完美封印(全库统一,含对外文案 3 处)/N2 板级→整图/ N3 门票→专长凭证(仅注释措辞)/N4 正主→现行事实源/N5 落籍→已入库/ N6 代码域静态扫描闸新增 S11「代码注释禁用词」规则。 上游依据=2026-10-19 用户裁(完美排雷全库统一换代为完美封印,含代码内部注释), 据此推翻 需求卡片-凭证件裁削批:108「内部开发用语按 v3.15 纪律保留」半句, 该卡片条款订正归文档轨批。 契约八条:标识符零改动(feat_ticket_*/SHELF_KINDS/存档键)/游戏行为零变化 (唯一例外=对外文案三处文本)/S11 先落规则后修码/S11 词表从术语表解析不内联/ S11 带扫描面零命中自检/禁碰并行会话在改文件(AGENTS.md/code-conventions.md)/ 对照性文本豁免。 不做(去向):design/ 全部文档归 reports/ 反哺点;门票标识符与数据键不动; shop.tres:86 与 curio_interact_controller.gd:165-166 移交文档侧定性; A 表词/流程动词/STC 通用词待用户另裁。 06 条目状态:待写卡 → 已写卡(卡片路径)。 流水线闸 PASS:卡片口径 22 张全过。 --- design/gdd/06-待办清单.md | 2 +- ...œ€求卡片-代码注释禁用词清扫批-2026-10-20.md | 296 ++++++++++++++++++ 2 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index f7e7c8d2..47e1c995 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -690,4 +690,4 @@ **归属**:game/ 代码与数据表(代码域,走独立 worktree 批;并行避让——`changelog-retire-20261019` 在盘未合回且正在改 `AGENTS.md` 与 `design/dev/code-conventions.md`,本批禁碰这两个文件,S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`) -**状态**:待写卡 +**状态**:已写卡(design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md) diff --git a/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md b/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md new file mode 100644 index 00000000..c7432982 --- /dev/null +++ b/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md @@ -0,0 +1,296 @@ +# 需求卡片·代码注释禁用词清扫批(退役词换代+完美排雷统一为完美封印) + +- **批次名**:代码注释禁用词清扫批 +- **日期**:2026-10-20 +- **批次性质**:工程债/重构(凭 06 在册条目直接写卡;工程直入四类,无设计前置要求) +- **设计事实源**(唯一事实源:`design/gdd/术语表.md`「退役词对照」+「用语规范 A 表」+「对外命名纪律」节;req-card 三选一之③工程直入证据指认):扫描读数=`game/` 下 195 个文件(.gd/.tres/.md/.json/.sh/.txt)逐处实测,落点带 file:line(见 §2);复现命令见 §2 末。 +- **版本**:v1.0 +- **迭代归属**:待编入 roadmap 迭代 32(本卡不自行编入;编排归 iter-plan 段) +- **上游依据**:2026-10-19 用户裁——「完美排雷」**全库统一**换代为「完美封印」,含代码内部注释 + +## 1. 目标与完成定义 + +**目标**:把术语表已在册的退役词从 `game/` 的代码注释里清干净,并把「完美排雷」统一为对外正式名「完美封印」;同时在**代码域自己的静态扫描闸**里补一条规则,让这类残留以后自动见红。 + +| 需求点 | 一句话 | +|---|---| +| **N1** | 「完美排雷」全库统一为「完美封印」(含对外文案 3 处、代码注释 13 处) | +| **N2** | 注释里「板级」换代为「整图」 | +| **N3** | 注释里「门票」换代为「专长凭证」(标识符与数据键零改动) | +| **N4** | 注释里「正主」换代为「现行事实源」 | +| **N5** | 注释里「落籍」换代为「已入库」 | +| **N6** | 代码域静态扫描闸新增 S11「代码注释禁用词」规则,先落规则再见红 | + +**完成定义**(全部满足才算完): + +1. `game/` 内 `完美排雷`/`板级`/`门票`(注释面)/`正主`/`落籍` 五词,**疑似现行计数全部为 0**(豁免=含对照/历史信号的行)。 +2. 对外文案三处不含「雷」字面,读作「完美封印」。 +3. 冒烟绿数与改前基线一致(现行 1151 项 0 失败)、单元测试 34 套全绿、探针段绿。 +4. S11 规则在位:注入一次禁用词 → `game/tests/static_scan.sh` 判红;还原后绿;变异验证记录进实现报告。 +5. 代码域闸按域选档跑通,回执 `game/tests/.gates/receipt.json` 的 commit = 分支 tip 且 `all_green=true`。 +6. `reports/` 三份产出物写齐(实现报告/代拍板追认单/反哺点清单)。 + +**文档面不在本卡完成定义内**——迭代批禁写 `design/` 整目录与根规则文件,唯一可写目录=`reports/`(process-conventions §3 第 13 条)。 + +## 2. 现状事实(2026-10-19 实测,开工自行复核) + +扫描范围:`game/` 下 195 个文件(.gd/.tres/.md/.json/.sh/.txt)。 +口径:命中行若含对照性/历史信号(`退役`/`作废`/`换装`/`继任`/`留档`/`历史`/`已删`/`不再`/`禁用`/`禁「`/`字面`/`原「`/`旧称`/`更名`/`换代`/`改为`/`→`/`禁令`/`引举`/`对照`/`豁免`/`待裁`/`已入库`/`登记`/`风味`)则不计入。 + +### N1 · 完美排雷(16 处 / 9 文件) + +| 落点 | 行 | 面 | +|---|---|---| +| `core/battle_orchestrator.gd` | 265、911 | 注释 | +| `core/battle_orchestrator.gd` | **925** | **对外文案**(`"完美排雷!清图奖励 ×2"`) | +| `core/battle_orchestrator.gd` | 1296 | `##` 文档注释(谓词说明) | +| `data/schemas/settlement_table.gd` | 8 | 注释 | +| `presentation/row_pacer.gd` | 92 | 注释 | +| `presentation/views/battle_log_view.gd` | **194** | **对外文案**(「本板完美排雷已破」) | +| `presentation/views/board_fx_view.gd` | 2、90 | 注释 | +| `presentation/views/board_fx_view.gd` | **102** | **对外文案**(`_show_banner("完美排雷 ×2")`) | +| `presentation/views/settlement_fx_view.gd` | 14 | 注释 | +| `game/README.md` | 146 | 文档正文 | +| `smoke/smoke_all.gd` | 3512、3516、4076、6201 | 注释/断言描述 | +| `tests/smoke/critical-paths.md` | 20 | 文档正文 | + +注:`battle_log_view.gd:194` 的病句已由 `design/qa/文案审查报告-2026-10-18.md:150` 点名,本批一并修掉。 + +### N2 · 板级(26 处 / 13 文件) + +`core/battle_orchestrator.gd`(67、265、470、482、506、507、928、1213)· `core/board_data.gd`(17、53)· `core/treasure_items.gd`(2、41)· `core/minesweeper_rules.gd`(126)· `data/schemas/variation_table.gd`(20、79)· `presentation/main.gd`(914)· `presentation/treasure_interact_controller.gd`(101)· `presentation/views/board_view.gd`(149、511)· `presentation/views/board_cell_unit.gd`(97)· `presentation/views/hero_info_panel_view.gd`(122、162)· `presentation/views/settlement_fx_view.gd`(146)· `smoke/smoke_all.gd`(2588、2630)· `tests/unit/core/feat_vouchers_test.gd`(174) + +### N3 · 门票(38 处 / 11 文件;其中 3 处移交,本批做 35 处) + +`core/adventure_runner.gd`(67、68、69、477、664、751、771、788、796、1033、1034)· `core/level_runner.gd`(51、781、826、831)· `data/schemas/adventure_table.gd`(92、96、97)· `data/schemas/shop_table.gd`(18)· `data/tables/shop.tres`(104)· `presentation/curio_interact_controller.gd`(89、217、237)· `presentation/views/curio_pick_overlay.gd`(110)· `smoke/level_autoplay.gd`(226)· `smoke/smoke_all.gd`(1362、1363、1370、1378、1379、1382、1384、5306)· `tests/unit/core/pool_case_d_test.gd`(98)· `tests/unit/presentation/reward_overlay_test.gd`(41) + +**移交 3 处**(不属本批,去向=文档轨批):`data/tables/shop.tres:86` display_name「奇物门票」、`presentation/curio_interact_controller.gd:165`/`:166` 玩家可见文案「奇物门票/开一次奇物三选一」。 + +### N4 · 正主(12 处 / 9 文件,含误报 1 处) + +`core/adventure_runner.gd:59` · `core/treasure_items.gd:57` · `presentation/views/board_cell_unit.gd:111`/`112` · `presentation/views/board_view.gd:122` · `smoke/board_shot_probe.gd:31` · `smoke/layout_probe.gd:2` · `smoke/shot_probe.gd:3`/`28` · `smoke/t17_defer_probe.gd:6`/`20` · `tests/unit/battle_settlement/damage_math_test.gd:36`(**误报**——「正主角池」是「正主」+「角池」,非词面命中,不改) + +### N5 · 落籍(10 处 / 4 文件,含历史注记 1 处) + +`core/config_db.gd`(22、23、42、45、280、337、390)· `data/tables/enemy.tres:653`(**历史注记**——「已落籍 9cc4b8b」带 commit 号,属留档文本,不追改)· `presentation/views/board_view.gd:35` · `tests/unit/data_config/config_db_test.gd:133` + +**已核实清零(迭代 31 成果,本批不重复动)**:`金币`/`插旗`/`标旗`/`雷格`/`惩罚格`/`旗` 在 `game/` 内疑似现行计数**均为 0**。残留 3 处「旗」全在闸门逻辑(`smoke/smoke_all.gd:1319` 禁字面检查)与字形检查夹具(`tests/unit/presentation/ui_font_asset_test.gd:18`/`:19`),属对照性文本。 + +**复现命令**(仓库根):`grep -rn "完美排雷\|板级\|门票\|正主\|落籍" game/ --include=*.gd --include=*.tres --include=*.md --include=*.json --include=*.sh` + +## 3. 设计契约(🔴 违反=L3 停机呈报) + +1. 🔴 **标识符零改动**——`feat_ticket_*`(`_feat_ticket_pity`/`_feat_ticket_sold`/`_feat_ticket_appeared`/`_redeem_feat_ticket()`/`_pool_ticket`/`feat_ticket_chance`/`feat_ticket_quota`)、`SHELF_KINDS` 的 `"feat_ticket"`、断点存档键 `"feat_ticket_pity"`/`"feat_ticket_sold"`(持久化在 `save.json` 的 `breakpoint.adventure_counters`)**一律不动**。改名会断旧存档与跨文件契约,且上游 `需求卡片-凭证件裁削批`:109 明列「feat_ticket 体系|与本批无关,不碰」。 +2. 🔴 **游戏行为零变化**——本批是纯中文文本替换,禁止改动任何逻辑、数值、权重、条件判断。唯一例外=对外文案三处的**文本内容**变更(改前「完美排雷」→改后「完美封印」),这是玩家可见文本变化,须登记实机目检项。 +3. 🔴 **对外文案只动三处**——`battle_orchestrator.gd:925`/`board_fx_view.gd:102`/`battle_log_view.gd:194`;其余对外文案(含 `shop.tres:86`、`curio_interact_controller.gd:165-166`)零改动。 +4. 🔴 **S11 规则先落、后修码**——先把规则写进 `game/tests/static_scan.sh` 并跑出红,再动注释(code-conventions 缺陷-规范对照表纪律)。 +5. 🔴 **S11 词表不内联第二份**——规则脚本从 `design/gdd/术语表.md`(「退役词对照」+「用语规范 A 表」两节)解析词面;禁止在脚本里另抄一份词表(单一事实源红线,ADR 漂移教训同类)。 +6. 🔴 **S11 必须带扫描面零命中自检**——先数一遍扫描面文件数,为零即判红(沿 S3 教训:路径写歪时自检一起歪、一起红,不会静默恒绿)。 +7. 🔴 **禁碰并行会话在改的文件**——`AGENTS.md` 与 `design/dev/code-conventions.md`(分支 `changelog-retire-20261019` 在盘未合回)。S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`。 +8. 🔴 **对照性文本豁免**——含退役/更名/禁令等信号的行不改写(术语表用语规范 B 类豁免条款)。 + +## 4. 范围边界 + +**做**: + +1. `game/` 内 `完美排雷`→`完美封印`(16 处,含对外文案 3 处) +2. `game/` 内注释面 `板级`→`整图`(26 处) +3. `game/` 内注释面 `门票`→`专长凭证`(35 处,剔除移交 3 处) +4. `game/` 内注释面 `正主`→`现行事实源`(11 处,剔除误报 1 处) +5. `game/` 内注释面 `落籍`→`已入库`(9 处,剔除历史注记 1 处) +6. 代码域静态扫描闸新增 S11 规则(含零命中自检) +7. `game/README.md`/`game/tests/README.md` 同步 +8. 全量冒烟+单元+探针验证,绿数与基线一致 + +**不做**(去向): + +| 不做的 | 去向 | +|---|---| +| `design/` 全部文档(术语表/战斗结算/地图战斗资源/难度曲线与Boss/art-bible/ux 各件/07 清单) | **反哺点**——落 `reports/iter32-反哺点-<日期>.md`,由用户在会话裁决后归文档轨批(迭代批禁写 `design/`) | +| `门票` 标识符与数据键(`feat_ticket_*`/`SHELF_KINDS`/存档键) | 上游卡 §4 明列不碰;若将来要改,另立独立批并连带处理存档兼容 | +| `shop.tres:86`「奇物门票」与 `curio_interact_controller.gd:165-166` 玩家文案 | 属 奇物/专长 归类表述,与 06「冒记案遗留待裁两项」第①项同源 → 交文档侧定性后另走传导批 | +| `AGENTS.md`/`design/dev/code-conventions.md` | 并行会话 `changelog-retire-20261019` 在盘未合回,本批禁碰 | +| 术语表 A 表词(不得 14/报错 18/对标 1/若干 1/buff 22) | 待用户另裁;裁入则新立 06 条目与卡片 | +| doc-conventions 第 4 节流程动词(收口 128/随批 20/台账 17/对拍 16/在飞 10/落文 2) | 同上 | +| 简明技术中文(STC)通用禁用词(缺省 105/情况 26/入参·出参 23/比较·较为·相对 22 等) | 同上 | +| 任何游戏逻辑/数值改动 | 禁止(本批纯文本替换) | + +## 5. 关联文档同步面(必填) + +| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 | +|---|---|---| +| `design/gdd/术语表.md`「退役词对照」节 | 「门票→专长凭证」行现指在册,代码侧换代后该行应保留(对照行合法);「完美排雷」未入表,玩家面正式名=「完美封印」应由文档侧登记 | **反哺点** | +| `design/gdd/systems/战斗循环/战斗结算.md`(:85/:108/:116/:139/:141/:161/:259/:342) | 全篇称「完美排雷」,与 `奇物.md` v3.18+ 的「完美封印」同名异称 | **反哺点** | +| `design/gdd/systems/战斗循环/地图战斗资源.md`(:155/:194) | 同上 | **反哺点** | +| `design/gdd/systems/冒险循环/难度曲线与Boss.md`(:224/:227/:313) | 同上 | **反哺点** | +| `design/gdd/systems/战斗循环/战斗表现.md`(:53/:68) | 同上 | **反哺点** | +| `design/gdd/systems/表现与支撑/HUD框架.md`(:277) | 同上 | **反哺点** | +| `design/gdd/ux/battle.md`(:85/:222/:422) | 同上 | **反哺点** | +| `design/gdd/ux/interaction-patterns.md`(:90) | 同上 | **反哺点** | +| `design/art/art-bible.md`(:8/:88/:562/:574) | 同上;另 :198/:211 的「金币」换代 GP 已由分支 `gpsweep-20261019` 完成但未合回 | **反哺点** | +| `design/gdd/07-体验验证清单.md`(:142) | 「完美排雷」措辞;本批对外文案变更需登记目检项 | **反哺点** | +| `game/README.md`(:146/:168/:267) | 措辞换代 | **本批直改**(文件在 `game/` 内) | +| `game/tests/README.md` | S11 规则说明与扫描面登记 | **本批直改** | +| `game/tests/static_scan.sh` | S11 规则承载 | **本批直改** | + +## 6. 任务卡 + +### 卡前·文件结构图 + +| 文件 | 职责 | 本批动作 | +|---|---|---| +| `game/tests/static_scan.sh` | 静态扫描域可执行承载(现 S1–S5、S9、S10) | 增 S11 段 | +| `game/tests/README.md` | 测试分层与闸口径登记 | 增 S11 说明 | +| `game/README.md` | 切片架构说明 | 措辞换代 | +| `game/core/battle_orchestrator.gd` | 战斗编排器 | 注释+对外文案换代 | +| `game/core/minesweeper_rules.gd` 等 12 个 .gd | 注释承载 | 注释换代 | +| `game/data/tables/*.tres` | 数据表注释 | 注释换代 | +| `game/smoke/smoke_all.gd` | 冒烟断言 | 注释与断言描述换代 | +| `game/tests/unit/**` | 单元测试 | 注释与断言描述换代 | + +### T0 · 基线记录(≈15 min) + +- [ ] 在 worktree 内跑全量冒烟,记录绿数(现行基线 1151 项 0 失败) +- [ ] 跑单元测试,记录套数与绿数(现行基线 34 套全绿) +- [ ] 跑 `bash game/tests/static_scan.sh`,记录现行退出码 0 +- [ ] 跑 §2 末复现命令,存改前命中清单(五词逐处),作为改后零残留的对照 + +**取用**:无(首卡)。 +**产出**:`reports/iter32-实现报告-<日期>.md` 的「改前基线」三数——`baseline_smoke_green:int`/`baseline_unit_suites:int`/`baseline_scan_exit:int`。 + +### T1 · S11 规则落闸并见红(≈1.0–1.5h) + +- [ ] 在 `game/tests/static_scan.sh` 头部注释的第 1–3 行补 S11 一行说明(规则名+权威出处+扫描面) +- [ ] 新增 S11 段:扫描面=`DIR_CORE`+`DIR_PRES` 下 `.gd`,逐行剔除注释行以外的代码行后取注释文本段 +- [ ] 词表面从 `design/gdd/术语表.md` 解析:取「退役词对照」表第一列全部词面(去括号注)+「用语规范」A 表「禁用」列全部词面 +- [ ] 规则先数扫描面文件数,为零即 `echo "[static_scan] S11 FAIL: 扫描面为空"` 并 `fail=1` +- [ ] 命中即打印 `file:line + 命中词`,段末 `fail=1` +- [ ] 注入验证:在 `game/core/battle_orchestrator.gd` 某注释里临时写回「板级」一词 → 跑 `bash game/tests/static_scan.sh` 见红并记输出摘要 → `git checkout -- game/core/battle_orchestrator.gd` 精确还原 → 记录进实现报告变异验证表 + +**取用**:无。 +**产出**:`game/tests/static_scan.sh` 的 `S11` 段(退出码语义=任一硬失败规则命中即 `exit 1`,与现役同段同规)。 + +### T2 · 完美排雷 → 完美封印(≈1.0h) + +- [ ] `game/core/battle_orchestrator.gd:925` 行内字符串 `"完美排雷!清图奖励 ×2"` 改为 `"完美封印!清图奖励 ×2"` +- [ ] `game/presentation/views/board_fx_view.gd:102` `_show_banner("完美排雷 ×2")` 改为 `_show_banner("完美封印 ×2")` +- [ ] `game/presentation/views/battle_log_view.gd:194` 病句改写:现 `"(本板完美排雷已破——归因此封印)"` → `"(本图完美封印已破——归因此次封印)"` +- [ ] 其余 13 处注释/文档正文逐处换代(清单见 §2 N1 表) +- [ ] 跑 §2 末复现命令确认 `完美排雷` 零命中 + +**取用**:无。 +**产出**:`game/` 内「完美排雷」零命中;对外文案三处读作「完美封印」。 + +### T3 · 板级 → 整图(≈1.0h) + +- [ ] `game/core/battle_orchestrator.gd` 8 处(67/265/470/482/506/507/928/1213)换代 +- [ ] `game/core/board_data.gd` 2 处(17/53)换代 +- [ ] 余 11 文件 16 处逐处换代(清单见 §2 N2) +- [ ] 跑 §2 末复现命令确认 `板级` 零命中 + +**取用**:无。 +**产出**:`game/` 内「板级」零命中。 + +### T4 · 门票 → 专长凭证(注释面,≈1.0h) + +- [ ] `game/core/adventure_runner.gd` 11 处注释换代(67/68/69/477/664/751/771/788/796/1033/1034) +- [ ] `game/core/level_runner.gd` 4 处(51/781/826/831) +- [ ] `game/data/schemas/adventure_table.gd` 3 处(92/96/97)+ `shop_table.gd:18` +- [ ] `game/data/tables/shop.tres:104` 注释换代 +- [ ] `game/presentation/curio_interact_controller.gd` 3 处(89/217/237)+ `curio_pick_overlay.gd:110` +- [ ] `game/smoke/level_autoplay.gd:226`+`smoke_all.gd` 8 处+`tests/**` 2 处换代 +- [ ] 复核标识符与数据键零改动(`feat_ticket` 族、`"feat_ticket"` 行族键、存档键) + +**取用**:无。 +**产出**:`game/` 注释面「门票」零命中;标识符与数据键保持原样。 + +### T5 · 正主 → 现行事实源(≈0.5h) + +- [ ] 11 处换代(清单见 §2 N4,剔除 `damage_math_test.gd:36` 误报) + +**取用**:无。 +**产出**:`game/` 内「正主」零命中。 + +### T6 · 落籍 → 已入库(≈0.5h) + +- [ ] 9 处换代(清单见 §2 N5,剔除 `enemy.tres:653` 历史注记) + +**取用**:无。 +**产出**:`game/` 内「落籍」零命中。 + +### T7 · 全量验证与产出物落位(≈1.0h) + +- [ ] 跑代码域档验收(按本批改动域选档),确认所选域全绿 +- [ ] 确认回执 `game/tests/.gates/receipt.json` 的 commit = 分支 tip 且 `all_green=true` +- [ ] 写 `reports/iter32-实现报告-<日期>.md`(各卡状态+改前改后读数对照+实机目检总清单+遗留读数义务) +- [ ] 写 `reports/iter32-代拍板-<日期>.md` +- [ ] 写 `reports/iter32-反哺点-<日期>.md`(§5 每条都要有落点) + +**取用**:T1–T6 全部产出。 +**产出**:`reports/` 三份产出物 + 可合回的分支 tip。 + +**估时合计 ≈6.5–7.5h**(不含并行会话等待)。超 8h 切分预案:T3/T4 各拆「核心层」与「呈现+测试」两卡串行施工,其余不动。 + +## 7. 验证闸 + +### 逐需求点验收清单 + +| # | 需求点 | 测什么(断言/行为) | 怎么测(落点) | 谁验 | +|---|---|---|---|---| +| A1 | N1 | `game/` 内 `完美排雷` 疑似现行计数 == 0 | grep 复现命令+同脚本口径 | 自动(S11+收尾 grep) | +| A2 | N1 | 对外文案三处文本恰为「完美封印…」,且不含「雷」字面 | 新冒烟断言:取清图高光行 `display_name`,断言 `find("雷") == -1` 且 `find("完美封印") >= 0`;落点 `game/smoke/smoke_all.gd` 清图段 | 自动(闸 01) | +| A3 | N2 | `game/` 内 `板级` 计数 == 0 | 同 A1 | 自动 | +| A4 | N3 | `game/` 注释面 `门票` 计数 == 0;且 `feat_ticket` 标识符与存档键**保持原样** | 同 A1 + 新增断言:`grep -c "feat_ticket"` 计数 == 改前值 | 自动 | +| A5 | N4 | `game/` 内 `正主` 计数 == 0 | 同 A1 | 自动 | +| A6 | N5 | `game/` 内 `落籍` 计数 == 0(历史注记行豁免) | 同 A1 | 自动 | +| A7 | N6 | S11 规则在位:注入禁用词 → 退出码 1 且输出含 `S11 FAIL`/命中行 | 注入实验(变异验证),落点 `game/tests/static_scan.sh` | 自动(人工执行一次取证) | +| A8 | 全域 | 冒烟绿数 == 基线 1151、单元 34 套全绿、探针段绿 | 跑所选域档 | 自动 | +| A9 | 全域 | 回执 commit == 分支 tip 且 `all_green=true`,零新增红 | 跑闸后读 `game/tests/.gates/receipt.json` | 自动(合回闸) | + +**测试方式两分法**:A1–A7 属能力验证(静态扫描/断言直取数据)与取证实验;A8–A9 为运行期验证。玩家可见文案的最终观感归**用户目检**(登记不阻塞):商店/图例/HUD 与结算高光行读作「完美封印/封印印记」。 + +**闸口径**:按本批改动域选档跑 `tools/run_all_gates.sh`(本批只触 `game/` 与 `reports/` → 代码域档);跑完写回执。 + +**回归措辞模板**:「里程碑步(波/T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试/工具先行孤立验证再并入全套」。 + +### 变异验证(新增判据必做) + +| 变异点 | 注入形态 | 跑的闸 | 期望红 | +|---|---|---|---| +| `game/core/battle_orchestrator.gd:265` 注释 | 写回「板级完美排雷」原措辞 | `bash game/tests/static_scan.sh` | `S11 FAIL` + 命中行输出 | +| 同上对外文案 | `game/core/battle_orchestrator.gd:925` 写回「完美排雷!…」 | 冒烟清图段 | 断言 A2 红 | +| S11 扫描面 | 临时把 `DIR_CORE` 改成不存在目录 | `bash game/tests/static_scan.sh` | `S11 FAIL: 扫描面为空` | + +注入后一律 `git checkout -- ` 精确还原,四件(变异点 file:行/跑的闸/红输出摘要/还原结论)记进实现报告变异验证记录表。 + +## 8. 异常分级 + +- **L1(自救)**:单文件漏改致 grep 未过 → 补改重跑该段,不改批结构。 +- **L2(记录继续)**:冒烟绿数与基线偏差 ≤2 且已归因到断言描述文本替换 → 记录偏差原因后继续。 +- **L3(停机呈报)**: + 1. 冒烟绿数下降 >2,或出现逻辑断言红(说明改动触及行为); + 2. `.tres` 加载失败或 schema 不同步; + 3. 改前改后同种子读数不一致; + 4. S11 注入后不变红(判据无效); + 5. 触碰并行会话在改文件(`AGENTS.md`/`design/dev/code-conventions.md`)。 + +## 9. 代拍板白名单 + +1. 注释换代时的措辞微调(如「板级变异」→「整图变异」vs「整图作用域变异」),语义等价即可。 +2. `落籍`→`已入库` 在带 commit 号的历史注记行**不改**(留档文本)。 +3. `正主` 误报处(`damage_math_test.gd:36`「正主角池」)不改。 +4. 测试断言描述文本的替换措辞,语义等价即可。 +5. S11 规则段的 shell 写法(grep 组合、计数方式),与现役 S 段同构即可。 + +超清单必呈报。 + +## 10. 待裁点 + +**零待裁点,开工门=U0(`/iter 32` 发令)。** + +已落裁决两条,卡片据以成文: + +| 裁定 | 结论 | +|---|---| +| 完美排雷 | 全库统一换代为「完美封印」(含代码内部注释)——2026-10-19 用户裁;据此推翻 `需求卡片-凭证件裁削批`:108「内部开发用语按 v3.15 纪律保留」半句,卡片条款订正归文档轨批 | +| 门票 | 仅换代注释措辞;标识符与数据键零改动;玩家可见两处(`shop.tres:86`/`curio_interact_controller.gd:165-166`)移交文档侧定性 | From bf5c379b325e916f3f2c59907cee352a4ca6d5a0 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 01:30:29 +0800 Subject: [PATCH 03/59] =?UTF-8?q?docs(card):=20=E9=9C=80=E6=B1=82=E5=8D=A1?= =?UTF-8?q?=E7=89=87=20v1.0=20=E4=BF=AE=E8=AE=A2=E2=80=94=E2=80=94S11=20?= =?UTF-8?q?=E6=89=AB=E6=8F=8F=E9=9D=A2=E6=94=B9=E5=85=A8=E5=9F=9F=EF=BC=8C?= =?UTF-8?q?N1=20=E8=90=BD=E7=82=B9=E6=8E=AA=E8=BE=9E=E8=AE=A2=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 按用户裁决(2026-10-20)落两处: - T1 S11 扫描面:由「game/core+game/presentation 下 .gd」改为「game/ 全域 (.gd/.tres/.md/.json)」,与迭代 31 V4 判据口径对齐——退役词残留同样落在 .tres 注释与 README.md,只扫 .gd 会漏。 - T2 第 4 步措辞订正:原「其余 13 处注释/文档正文」不准确,改为 「11 处代码注释/文档注释 + 4 处冒烟断言描述文本与夹具期望字面量」 (smoke_all.gd:3512/3516/4076/6201 中 6201 是断言比对的期望字面量,非注释)。 另两条按推荐锁定:Q2=门票标识符与数据键零改动;Q3=S11 扫描面取全域。 --- design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md b/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md index c7432982..451930a8 100644 --- a/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md +++ b/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md @@ -161,7 +161,7 @@ ### T1 · S11 规则落闸并见红(≈1.0–1.5h) - [ ] 在 `game/tests/static_scan.sh` 头部注释的第 1–3 行补 S11 一行说明(规则名+权威出处+扫描面) -- [ ] 新增 S11 段:扫描面=`DIR_CORE`+`DIR_PRES` 下 `.gd`,逐行剔除注释行以外的代码行后取注释文本段 +- [ ] 新增 S11 段:扫描面=`game/` 全域(.gd/.tres/.md/.json),与迭代 31 V4 判据同口径;逐行取注释文本段(`#`/`;` 前缀),剔除含对照/历史信号的行 - [ ] 词表面从 `design/gdd/术语表.md` 解析:取「退役词对照」表第一列全部词面(去括号注)+「用语规范」A 表「禁用」列全部词面 - [ ] 规则先数扫描面文件数,为零即 `echo "[static_scan] S11 FAIL: 扫描面为空"` 并 `fail=1` - [ ] 命中即打印 `file:line + 命中词`,段末 `fail=1` @@ -175,7 +175,7 @@ - [ ] `game/core/battle_orchestrator.gd:925` 行内字符串 `"完美排雷!清图奖励 ×2"` 改为 `"完美封印!清图奖励 ×2"` - [ ] `game/presentation/views/board_fx_view.gd:102` `_show_banner("完美排雷 ×2")` 改为 `_show_banner("完美封印 ×2")` - [ ] `game/presentation/views/battle_log_view.gd:194` 病句改写:现 `"(本板完美排雷已破——归因此封印)"` → `"(本图完美封印已破——归因此次封印)"` -- [ ] 其余 13 处注释/文档正文逐处换代(清单见 §2 N1 表) +- [ ] 其余 13 处(11 处代码注释/文档注释 + 4 处冒烟断言描述文本与夹具期望字面量)逐处换代(清单见 §2 N1 表) - [ ] 跑 §2 末复现命令确认 `完美排雷` 零命中 **取用**:无。 From 8575e1b16c06c50bebf569e35dd5c4a56102e662 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 02:04:42 +0800 Subject: [PATCH 04/59] =?UTF-8?q?docs(card):=20=E9=9C=80=E6=B1=82=E5=8D=A1?= =?UTF-8?q?=E7=89=87=20v1.1=E2=80=94=E2=80=94=E6=96=B0=E5=A2=9E=20N7=20?= =?UTF-8?q?=E5=BD=92=E5=9B=A0=E9=94=9A=E5=88=A4=E6=8D=AE=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=EF=BC=8CT2=20=E5=AF=B9=E5=A4=96=E6=96=87=E6=A1=88=E6=94=B9?= =?UTF-8?q?=E6=A6=82=E5=BF=B5=E9=A9=B1=E5=8A=A8=E4=B8=A4=E6=80=81=E5=86=99?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit grilling 复核门查出概念冲突,按用户 2026-10-20 裁定(Q5=A)并入本批: **新增 §0 概念定义节**:明确「完美封印」=一张图的**清图奖励加倍条件**—— 判据=零有效误标 且 至少一次封印标中;有效误标=误标总数 − 豁免数; 成立效果=清图奖励追加第二份同身份兑付;被破之后=只发一份不加倍。 出处:战斗结算.md:161 本体/:108 当量公式/:116 乘数字义/:321 调参表。 **新增 N7(真缺陷)**:`grant_segment.gd:300` 用 RAW 计数 `_perfect_hit_false == 1` 判「已破」,而 `battle_orchestrator.gd:1299` `perfect_sweep_earned()` 用有效误标;豁免累加(:314)又排在 `_emit_row` (:302)之后。⇒ 装备「完美保险」时日志打印「已破」,实际加倍照发, 日志断言了与真值相反的状态。修法:判据改 `_perfect_hit_false - _perfect_forgiven == 1`,豁免累加上移到 `_emit_row` 之前。 **T2 措辞订正**:对外文案不再作机械换词,改为按 §0 概念的两态改写—— 未豁免态 `(本图完美封印已破——清图奖励不再加倍)`; 已豁免态 `(首次封印落空已豁免——不计入完美封印判定)` (后者与 feats.tres:861 desc 口径一致)。 原三候选(机械换词)作废。 **契约增两条**:语义先行禁纯词面替换;完美封印判据单点(只允许由 perfect_sweep_earned() 派生,两处不一致即缺陷)。 **验收清单增 A10/A11**(未豁免态应「已破」、豁免态应无「已破」), 变异验证增两条(N7 判据正/反)。 估时由 ≈6.5–7.5h 上调为 ≈8.5–10.0h,切分预案同步。 流水线闸 PASS:卡片口径 22 张全过。 --- design/gdd/06-待办清单.md | 4 +- ...œ€求卡片-代码注释禁用词清扫批-2026-10-20.md | 214 +++++++++++++----- 2 files changed, 158 insertions(+), 60 deletions(-) diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index 47e1c995..daf71dbb 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -678,7 +678,7 @@ --- -#### 代码注释禁用词清扫批——退役词换代+完美排雷统一为完美封印(2026-10-20 登记,来源=会话提及,设计面=工程直入) +#### 代码注释禁用词清扫批——退役词换代+完美封印统一+归因锚判据修正(2026-10-20 登记,来源=会话提及,设计面=工程直入) **现状**:2026-10-19 全量扫描 `game/`(195 个文件:.gd/.tres/.md/.json/.sh/.txt)的可复核实测读数,口径=剔除含对照性/历史信号的行后计「疑似现行残留」。 **确定违规**(术语表「退役词对照」在册,落于代码注释面)=`板级` 26 处/`门票` 38 处/`正主` 12 处(含 `tests/unit/battle_settlement/damage_math_test.gd:36`「正主角池」误报 1 处)/`落籍` 10 处(含 `data/tables/enemy.tres:653` 带 commit 号的历史注记 1 处,不追改)。 @@ -686,6 +686,8 @@ **根因**:迭代 31 卡① 完成判据 V4 只覆盖「金币/插旗/雷格/惩罚格」四词(+旗族),`排雷`/`雷`族未入完成判据;且机检闸 `tools/doc_term_audit.py` 的 `DEFAULT_DIRS = ["design/gdd"]`,**代码注释面从未进闸**——不清根则同类残留持续复发。 **裁定(2026-10-19 用户)**:完美排雷**全库统一**换代为「完美封印」,含代码内部注释。本裁**推翻** `需求卡片-凭证件裁削批`:108「内部开发用语按 v3.15 纪律保留」半句,该卡片条款订正归**文档轨批**,代码批照本裁执行。 **移交(不属本批)**:`game/data/tables/shop.tres:86` display_name「奇物门票」、`game/presentation/curio_interact_controller.gd:165-166`「开一次奇物三选一」——两处属 奇物/专长 归类表述,与 06「2026-10-18 冒记案遗留待裁两项」第①项同源,交文档侧先定性,定后另走传导批。 +**扫描中查出的真缺陷(N7)**:`core/settlement/grant_segment.gd:300` 用 RAW 误标计数判「完美封印已破」,而 `core/battle_orchestrator.gd:1299` 的真正谓词用**有效误标**(总数 − 豁免数);且豁免累加(:314)排在 `_emit_row`(:302)之后。⇒ 装备「完美保险」时日志打印「已破」,实际加倍奖励仍发,日志与真值矛盾。2026-10-20 用户裁=并入本批修(判据改有效误标+豁免上移+文案两态)。 + **不做(待用户另裁)**:术语表 A 表词(`不得` 14/`报错` 18/`对标` 1/`若干` 1/`buff` 22——后者绝大多数是标识符与数据键)、doc-conventions 第 4 节流程动词(`收口` 128/`随批` 20/`台账` 17/`对拍` 16/`在飞` 10/`落文` 2)、简明技术中文(STC)通用禁用词(`缺省` 105/`情况` 26/`入参|出参` 23/`比较|较为|相对` 22 等)。 **归属**:game/ 代码与数据表(代码域,走独立 worktree 批;并行避让——`changelog-retire-20261019` 在盘未合回且正在改 `AGENTS.md` 与 `design/dev/code-conventions.md`,本批禁碰这两个文件,S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`) diff --git a/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md b/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md index 451930a8..5ea88db3 100644 --- a/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md +++ b/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md @@ -1,38 +1,70 @@ -# 需求卡片·代码注释禁用词清扫批(退役词换代+完美排雷统一为完美封印) +# 需求卡片·代码注释禁用词清扫批(退役词换代+完美封印统一+归因锚判据修正) - **批次名**:代码注释禁用词清扫批 - **日期**:2026-10-20 -- **批次性质**:工程债/重构(凭 06 在册条目直接写卡;工程直入四类,无设计前置要求) -- **设计事实源**(唯一事实源:`design/gdd/术语表.md`「退役词对照」+「用语规范 A 表」+「对外命名纪律」节;req-card 三选一之③工程直入证据指认):扫描读数=`game/` 下 195 个文件(.gd/.tres/.md/.json/.sh/.txt)逐处实测,落点带 file:line(见 §2);复现命令见 §2 末。 -- **版本**:v1.0 +- **批次性质**:工程债/重构 + 缺陷修复(两类均属工程直入四类,凭 06 在册条目与代码级证据直接写卡) +- **设计事实源**(唯一事实源:`design/gdd/术语表.md`「退役词对照」+「用语规范 A 表」+「对外命名纪律」节;`design/gdd/systems/战斗循环/战斗结算.md`「完美排雷」规则节;req-card 三选一之③工程直入证据指认):扫描读数=`game/` 下 195 个文件(.gd/.tres/.md/.json/.sh/.txt)逐处实测,落点带 file:line(见 §2);复现命令见 §2 末。 +- **版本**:**v1.1**(2026-10-20:grilling 复核门查出 N7 概念冲突,新增需求点与 T7 卡;T2 的对外文案由「机械换词」改为「按概念两态改写」) - **迭代归属**:待编入 roadmap 迭代 32(本卡不自行编入;编排归 iter-plan 段) - **上游依据**:2026-10-19 用户裁——「完美排雷」**全库统一**换代为「完美封印」,含代码内部注释 -## 1. 目标与完成定义 +--- -**目标**:把术语表已在册的退役词从 `game/` 的代码注释里清干净,并把「完美排雷」统一为对外正式名「完美封印」;同时在**代码域自己的静态扫描闸**里补一条规则,让这类残留以后自动见红。 +## 0 · 概念定义(动笔前必读,本卡所有措辞以此为准) + +**完美封印**(玩家面正式名;机制文档旧称「完美排雷」)= **一张图的清图奖励加倍条件**。 + +| 项 | 内容 | +|---|---| +| 成立判据 | 一张图「零有效误标」**且**「至少一次封印标中」 | +| 有效误标 | = 误标总数 − 豁免数(迭代 31 卡② T4 落的两账相减口径) | +| 计数纯净 | `_perfect_hit_false` 全程不被任何效果改写;豁免只累加 `_perfect_forgiven` | +| 成立效果 | 清图奖励对象追加**第二份同身份**兑付(乘数 `p_perfect`,现行值读 `settlement.tres`) | +| **被破之后** | 不再满足零有效误标 ⇒ 完美封印不成立 ⇒ **清图奖励只发一份,不加倍** | +| 计数起算 | 从装板起算;换图重置 | +| 高光行 | 成立时发一行;首份即零兑付则高光行不发 | + +**出处**: +- 规则本体 — `design/gdd/systems/战斗循环/战斗结算.md:161` +- 当量公式 — 同文件 :108(`完美排雷的清图奖励: E = 奖励表值 × 完美乘数 ÷ 100`) +- 乘数字义 — 同文件 :116 +- 调参表 — 同文件 :321(`完美乘数 | percent {100, 200} | 100 为仅高光、无第二份`) +- 清图批 — 同文件 :139;刷新图重置 — :259 +- 兑付结构 — `design/gdd/systems/战斗循环/地图战斗资源.md:155`/:194 + +**玩家面命名纪律**:术语表「对外命名纪律」禁「雷」字面进对外命名,适用范围**含 UI 文案**;该概念的玩家面正式名=「完美封印」,现由 `design/gdd/systems/冒险循环/奇物.md` v3.18 与 `game/data/tables/feats.tres:861` desc 在用。 + +--- + +## 1 · 目标与完成定义 + +**目标**:把术语表已在册的退役词从 `game/` 的代码注释里清干净,把「完美排雷」统一为玩家面正式名「完美封印」,修掉扫描中查出的归因锚判据矛盾;同时在**代码域自己的静态扫描闸**里补一条规则,让这类残留以后自动见红。 | 需求点 | 一句话 | |---|---| -| **N1** | 「完美排雷」全库统一为「完美封印」(含对外文案 3 处、代码注释 13 处) | +| **N1** | 「完美排雷」全库统一为「完美封印」(对外文案 3 处 / 代码注释与内部文档 13 处) | | **N2** | 注释里「板级」换代为「整图」 | | **N3** | 注释里「门票」换代为「专长凭证」(标识符与数据键零改动) | | **N4** | 注释里「正主」换代为「现行事实源」 | | **N5** | 注释里「落籍」换代为「已入库」 | | **N6** | 代码域静态扫描闸新增 S11「代码注释禁用词」规则,先落规则再见红 | +| **N7** | 封印未中行的「完美封印已破」归因锚改用**有效误标**判据,文案按「未豁免/已豁免」两态改写 | **完成定义**(全部满足才算完): 1. `game/` 内 `完美排雷`/`板级`/`门票`(注释面)/`正主`/`落籍` 五词,**疑似现行计数全部为 0**(豁免=含对照/历史信号的行)。 2. 对外文案三处不含「雷」字面,读作「完美封印」。 -3. 冒烟绿数与改前基线一致(现行 1151 项 0 失败)、单元测试 34 套全绿、探针段绿。 -4. S11 规则在位:注入一次禁用词 → `game/tests/static_scan.sh` 判红;还原后绿;变异验证记录进实现报告。 -5. 代码域闸按域选档跑通,回执 `game/tests/.gates/receipt.json` 的 commit = 分支 tip 且 `all_green=true`。 -6. `reports/` 三份产出物写齐(实现报告/代拍板追认单/反哺点清单)。 +3. **N7**:装备「完美保险」专长时本战首次标错 → 日志**不**出现「已破」字样,改出现豁免态文案;未装备时首次标错 → 出现「已破」态文案。两态各有正向断言。 +4. 冒烟绿数与改前基线一致(现行 1151 项 0 失败)、单元测试 34 套全绿、探针段绿。 +5. S11 规则在位:注入一次禁用词 → `game/tests/static_scan.sh` 判红;还原后绿;变异验证记录进实现报告。 +6. 代码域闸按域选档跑通,回执 `game/tests/.gates/receipt.json` 的 commit = 分支 tip 且 `all_green=true`。 +7. `reports/` 三份产出物写齐(实现报告/代拍板追认单/反哺点清单)。 **文档面不在本卡完成定义内**——迭代批禁写 `design/` 整目录与根规则文件,唯一可写目录=`reports/`(process-conventions §3 第 13 条)。 -## 2. 现状事实(2026-10-19 实测,开工自行复核) +--- + +## 2 · 现状事实(2026-10-19 实测,开工自行复核) 扫描范围:`game/` 下 195 个文件(.gd/.tres/.md/.json/.sh/.txt)。 口径:命中行若含对照性/历史信号(`退役`/`作废`/`换装`/`继任`/`留档`/`历史`/`已删`/`不再`/`禁用`/`禁「`/`字面`/`原「`/`旧称`/`更名`/`换代`/`改为`/`→`/`禁令`/`引举`/`对照`/`豁免`/`待裁`/`已入库`/`登记`/`风味`)则不计入。 @@ -51,11 +83,10 @@ | `presentation/views/board_fx_view.gd` | **102** | **对外文案**(`_show_banner("完美排雷 ×2")`) | | `presentation/views/settlement_fx_view.gd` | 14 | 注释 | | `game/README.md` | 146 | 文档正文 | -| `smoke/smoke_all.gd` | 3512、3516、4076、6201 | 注释/断言描述 | +| `smoke/smoke_all.gd` | 3512、3516、4076 | 注释/断言描述 | +| `smoke/smoke_all.gd` | **6201** | **冒烟夹具期望字面量**(断言比对用,非注释) | | `tests/smoke/critical-paths.md` | 20 | 文档正文 | -注:`battle_log_view.gd:194` 的病句已由 `design/qa/文案审查报告-2026-10-18.md:150` 点名,本批一并修掉。 - ### N2 · 板级(26 处 / 13 文件) `core/battle_orchestrator.gd`(67、265、470、482、506、507、928、1213)· `core/board_data.gd`(17、53)· `core/treasure_items.gd`(2、41)· `core/minesweeper_rules.gd`(126)· `data/schemas/variation_table.gd`(20、79)· `presentation/main.gd`(914)· `presentation/treasure_interact_controller.gd`(101)· `presentation/views/board_view.gd`(149、511)· `presentation/views/board_cell_unit.gd`(97)· `presentation/views/hero_info_panel_view.gd`(122、162)· `presentation/views/settlement_fx_view.gd`(146)· `smoke/smoke_all.gd`(2588、2630)· `tests/unit/core/feat_vouchers_test.gd`(174) @@ -74,22 +105,48 @@ `core/config_db.gd`(22、23、42、45、280、337、390)· `data/tables/enemy.tres:653`(**历史注记**——「已落籍 9cc4b8b」带 commit 号,属留档文本,不追改)· `presentation/views/board_view.gd:35` · `tests/unit/data_config/config_db_test.gd:133` -**已核实清零(迭代 31 成果,本批不重复动)**:`金币`/`插旗`/`标旗`/`雷格`/`惩罚格`/`旗` 在 `game/` 内疑似现行计数**均为 0**。残留 3 处「旗」全在闸门逻辑(`smoke/smoke_all.gd:1319` 禁字面检查)与字形检查夹具(`tests/unit/presentation/ui_font_asset_test.gd:18`/`:19`),属对照性文本。 +### N7 · 归因锚判据与概念定义矛盾(真缺陷,本批一并修) + +三个落点构成一条矛盾链: + +| # | 落点 | 现状 | +|---|---|---| +| 1 | `core/settlement/grant_segment.gd:295` | `oc._perfect_hit_false += 1` —— 累加的是 **RAW 误标总数** | +| 2 | `core/settlement/grant_segment.gd:300-301` | `if oc._perfect_hit_false == 1: hl = "perfect_broken"` —— 判据**只看 RAW 计数** | +| 3 | `core/battle_orchestrator.gd:1298-1299` | `perfect_sweep_earned()` 用的却是**有效误标**=`_perfect_hit_false − _perfect_forgiven <= 0` | + +**矛盾实证**:`grant_segment.gd:308-315` 里 `_fx_emit("seal_missed")` 与 `_perfect_forgiven += 1`(:314)都排在 `_emit_row`(:302)**之后**。装备「完美保险」专长时: +- 第 300 行 RAW 计数 `== 1` 成立 ⇒ 打印「完美封印已破」 +- 但第 314 行随后把 `_perfect_forgiven` 加到 1 ⇒ 有效误标 = 0 ⇒ `perfect_sweep_earned()` 仍为 **true**,加倍奖励照发 + +⇒ **日志告诉玩家"加倍没了",实际加倍还在。** 这不是病句,是断言了与真值相反的状态。 + +引用口径:`奇物.md` v3.18 已改用「完美封印」;`feats.tres:861` desc =「本场首次封印落空,不计入完美封印判定」。 + +### 已核实清零(迭代 31 成果,本批不重复动) + +`金币`/`插旗`/`标旗`/`雷格`/`惩罚格`/`旗` 在 `game/` 内疑似现行计数**均为 0**。残留 3 处「旗」全在闸门逻辑(`smoke/smoke_all.gd:1319` 禁字面检查)与字形检查夹具(`tests/unit/presentation/ui_font_asset_test.gd:18`/`:19`),属对照性文本。 **复现命令**(仓库根):`grep -rn "完美排雷\|板级\|门票\|正主\|落籍" game/ --include=*.gd --include=*.tres --include=*.md --include=*.json --include=*.sh` -## 3. 设计契约(🔴 违反=L3 停机呈报) +--- + +## 3 · 设计契约(🔴 违反=L3 停机呈报) 1. 🔴 **标识符零改动**——`feat_ticket_*`(`_feat_ticket_pity`/`_feat_ticket_sold`/`_feat_ticket_appeared`/`_redeem_feat_ticket()`/`_pool_ticket`/`feat_ticket_chance`/`feat_ticket_quota`)、`SHELF_KINDS` 的 `"feat_ticket"`、断点存档键 `"feat_ticket_pity"`/`"feat_ticket_sold"`(持久化在 `save.json` 的 `breakpoint.adventure_counters`)**一律不动**。改名会断旧存档与跨文件契约,且上游 `需求卡片-凭证件裁削批`:109 明列「feat_ticket 体系|与本批无关,不碰」。 -2. 🔴 **游戏行为零变化**——本批是纯中文文本替换,禁止改动任何逻辑、数值、权重、条件判断。唯一例外=对外文案三处的**文本内容**变更(改前「完美排雷」→改后「完美封印」),这是玩家可见文本变化,须登记实机目检项。 -3. 🔴 **对外文案只动三处**——`battle_orchestrator.gd:925`/`board_fx_view.gd:102`/`battle_log_view.gd:194`;其余对外文案(含 `shop.tres:86`、`curio_interact_controller.gd:165-166`)零改动。 -4. 🔴 **S11 规则先落、后修码**——先把规则写进 `game/tests/static_scan.sh` 并跑出红,再动注释(code-conventions 缺陷-规范对照表纪律)。 -5. 🔴 **S11 词表不内联第二份**——规则脚本从 `design/gdd/术语表.md`(「退役词对照」+「用语规范 A 表」两节)解析词面;禁止在脚本里另抄一份词表(单一事实源红线,ADR 漂移教训同类)。 -6. 🔴 **S11 必须带扫描面零命中自检**——先数一遍扫描面文件数,为零即判红(沿 S3 教训:路径写歪时自检一起歪、一起红,不会静默恒绿)。 -7. 🔴 **禁碰并行会话在改的文件**——`AGENTS.md` 与 `design/dev/code-conventions.md`(分支 `changelog-retire-20261019` 在盘未合回)。S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`。 -8. 🔴 **对照性文本豁免**——含退役/更名/禁令等信号的行不改写(术语表用语规范 B 类豁免条款)。 +2. 🔴 **对外文案只动三处**——`battle_orchestrator.gd:925`/`board_fx_view.gd:102`/`battle_log_view.gd:194`;其余对外文案(含 `shop.tres:86`、`curio_interact_controller.gd:165-166`)零改动。 +3. 🔴 **语义先行,禁纯词面替换**(grilling 复核门查出后立)——改写玩家可见文案前,必须先读 §0 概念定义并确认这句在讲什么;机检只能判字面,判不了语义对错。 +4. 🔴 **完美封印判据单点**——「是否已破」只允许由 `battle_orchestrator.perfect_sweep_earned()` 的有效误标口径派生,禁在 `grant_segment.gd` 另立 RAW 计数判据;两处口径不一致即为缺陷。 +5. 🔴 **游戏行为零变化**(N1–N5、N7 判据修正前)——纯中文文本替换,禁止改动逻辑、数值、权重、条件判断。N7 判据修正是**本批唯一允许的逻辑改动**,其验收为「日志文案与真值一致」,不改奖励兑付结果。 +6. 🔴 **S11 规则先落、后修码**——先把规则写进 `game/tests/static_scan.sh` 并跑出红,再动注释(code-conventions 缺陷-规范对照表纪律)。 +7. 🔴 **S11 词表不内联第二份**——规则脚本从 `design/gdd/术语表.md`(「退役词对照」+「用语规范 A 表」两节)解析词面;禁止在脚本里另抄一份词表(单一事实源红线,ADR 漂移教训同类)。 +8. 🔴 **S11 必须带扫描面零命中自检**——先数一遍扫描面文件数,为零即判红(沿 S3 教训:路径写歪时自检一起歪、一起红,不会静默恒绿)。 +9. 🔴 **禁碰并行会话在改的文件**——`AGENTS.md` 与 `design/dev/code-conventions.md`(分支 `changelog-retire-20261019` 在盘未合回)。S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`。 +10. 🔴 **对照性文本豁免**——含退役/更名/禁令等信号的行不改写(术语表用语规范 B 类豁免条款)。 -## 4. 范围边界 +--- + +## 4 · 范围边界 **做**: @@ -98,9 +155,11 @@ 3. `game/` 内注释面 `门票`→`专长凭证`(35 处,剔除移交 3 处) 4. `game/` 内注释面 `正主`→`现行事实源`(11 处,剔除误报 1 处) 5. `game/` 内注释面 `落籍`→`已入库`(9 处,剔除历史注记 1 处) -6. 代码域静态扫描闸新增 S11 规则(含零命中自检) -7. `game/README.md`/`game/tests/README.md` 同步 -8. 全量冒烟+单元+探针验证,绿数与基线一致 +6. `game/` 内 `完美排雷`→`完美封印`(16 处) +7. **N7**:封印未中行归因锚改用有效误标判据,文案按两态改写 +8. 代码域静态扫描闸新增 S11 规则(含零命中自检) +9. `game/README.md`/`game/tests/README.md` 同步 +10. 全量冒烟+单元+探针验证,绿数与基线一致 **不做**(去向): @@ -113,13 +172,15 @@ | 术语表 A 表词(不得 14/报错 18/对标 1/若干 1/buff 22) | 待用户另裁;裁入则新立 06 条目与卡片 | | doc-conventions 第 4 节流程动词(收口 128/随批 20/台账 17/对拍 16/在飞 10/落文 2) | 同上 | | 简明技术中文(STC)通用禁用词(缺省 105/情况 26/入参·出参 23/比较·较为·相对 22 等) | 同上 | -| 任何游戏逻辑/数值改动 | 禁止(本批纯文本替换) | +| 任何游戏逻辑/数值改动(N7 判据修正除外) | 禁止 | -## 5. 关联文档同步面(必填) +--- + +## 5 · 关联文档同步面(必填) | 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 | |---|---|---| -| `design/gdd/术语表.md`「退役词对照」节 | 「门票→专长凭证」行现指在册,代码侧换代后该行应保留(对照行合法);「完美排雷」未入表,玩家面正式名=「完美封印」应由文档侧登记 | **反哺点** | +| `design/gdd/术语表.md` | 「退役词对照」节有「门票→专长凭证」行,代码侧换代后该对照行应保留(对照行合法);「完美封印」尚未入表,玩家面正式名应由文档侧登记 | **反哺点** | | `design/gdd/systems/战斗循环/战斗结算.md`(:85/:108/:116/:139/:141/:161/:259/:342) | 全篇称「完美排雷」,与 `奇物.md` v3.18+ 的「完美封印」同名异称 | **反哺点** | | `design/gdd/systems/战斗循环/地图战斗资源.md`(:155/:194) | 同上 | **反哺点** | | `design/gdd/systems/冒险循环/难度曲线与Boss.md`(:224/:227/:313) | 同上 | **反哺点** | @@ -133,7 +194,9 @@ | `game/tests/README.md` | S11 规则说明与扫描面登记 | **本批直改** | | `game/tests/static_scan.sh` | S11 规则承载 | **本批直改** | -## 6. 任务卡 +--- + +## 6 · 任务卡 ### 卡前·文件结构图 @@ -143,9 +206,10 @@ | `game/tests/README.md` | 测试分层与闸口径登记 | 增 S11 说明 | | `game/README.md` | 切片架构说明 | 措辞换代 | | `game/core/battle_orchestrator.gd` | 战斗编排器 | 注释+对外文案换代 | -| `game/core/minesweeper_rules.gd` 等 12 个 .gd | 注释承载 | 注释换代 | +| `game/core/settlement/grant_segment.gd` | 授予段 | 注释换代 + **N7 判据修正** | +| `game/core/minesweeper_rules.gd` 等 11 个 .gd | 注释承载 | 注释换代 | | `game/data/tables/*.tres` | 数据表注释 | 注释换代 | -| `game/smoke/smoke_all.gd` | 冒烟断言 | 注释与断言描述换代 | +| `game/smoke/smoke_all.gd` | 冒烟断言 | 注释、断言描述与夹具期望字面量换代 | | `game/tests/unit/**` | 单元测试 | 注释与断言描述换代 | ### T0 · 基线记录(≈15 min) @@ -154,15 +218,17 @@ - [ ] 跑单元测试,记录套数与绿数(现行基线 34 套全绿) - [ ] 跑 `bash game/tests/static_scan.sh`,记录现行退出码 0 - [ ] 跑 §2 末复现命令,存改前命中清单(五词逐处),作为改后零残留的对照 +- [ ] 取证「豁免态下日志仍打印已破」:装 `perfect_insurance` 专长 → 首次标错 → 打印日志行原文 **取用**:无(首卡)。 -**产出**:`reports/iter32-实现报告-<日期>.md` 的「改前基线」三数——`baseline_smoke_green:int`/`baseline_unit_suites:int`/`baseline_scan_exit:int`。 +**产出**:`reports/iter32-实现报告-<日期>.md` 的「改前基线」四数——`baseline_smoke_green:int`/`baseline_unit_suites:int`/`baseline_scan_exit:int`/`baseline_forgiven_log_line:String`。 ### T1 · S11 规则落闸并见红(≈1.0–1.5h) -- [ ] 在 `game/tests/static_scan.sh` 头部注释的第 1–3 行补 S11 一行说明(规则名+权威出处+扫描面) -- [ ] 新增 S11 段:扫描面=`game/` 全域(.gd/.tres/.md/.json),与迭代 31 V4 判据同口径;逐行取注释文本段(`#`/`;` 前缀),剔除含对照/历史信号的行 -- [ ] 词表面从 `design/gdd/术语表.md` 解析:取「退役词对照」表第一列全部词面(去括号注)+「用语规范」A 表「禁用」列全部词面 +- [ ] 在 `game/tests/static_scan.sh` 头部注释补 S11 一行说明(规则名+权威出处+扫描面) +- [ ] 新增 S11 段:扫描面=`game/` 全域(.gd/.tres/.md/.json),与迭代 31 V4 判据同口径 +- [ ] 逐行取注释文本段(`#`/`;` 前缀),剔除含对照/历史信号的行 +- [ ] 词表面从 `design/gdd/术语表.md` 解析:「退役词对照」表第一列全部词面(去括号注)+「用语规范」A 表「禁用」列全部词面 - [ ] 规则先数扫描面文件数,为零即 `echo "[static_scan] S11 FAIL: 扫描面为空"` 并 `fail=1` - [ ] 命中即打印 `file:line + 命中词`,段末 `fail=1` - [ ] 注入验证:在 `game/core/battle_orchestrator.gd` 某注释里临时写回「板级」一词 → 跑 `bash game/tests/static_scan.sh` 见红并记输出摘要 → `git checkout -- game/core/battle_orchestrator.gd` 精确还原 → 记录进实现报告变异验证表 @@ -170,12 +236,14 @@ **取用**:无。 **产出**:`game/tests/static_scan.sh` 的 `S11` 段(退出码语义=任一硬失败规则命中即 `exit 1`,与现役同段同规)。 -### T2 · 完美排雷 → 完美封印(≈1.0h) +### T2 · 完美排雷 → 完美封印(≈1.5h) -- [ ] `game/core/battle_orchestrator.gd:925` 行内字符串 `"完美排雷!清图奖励 ×2"` 改为 `"完美封印!清图奖励 ×2"` -- [ ] `game/presentation/views/board_fx_view.gd:102` `_show_banner("完美排雷 ×2")` 改为 `_show_banner("完美封印 ×2")` -- [ ] `game/presentation/views/battle_log_view.gd:194` 病句改写:现 `"(本板完美排雷已破——归因此封印)"` → `"(本图完美封印已破——归因此次封印)"` -- [ ] 其余 13 处(11 处代码注释/文档注释 + 4 处冒烟断言描述文本与夹具期望字面量)逐处换代(清单见 §2 N1 表) +**判据(先立后改,§0 为准)**:这句日志在讲「本图的完美封印资格被这次标错打破 ⇒ 清图奖励不再加倍」。 + +- [ ] `game/core/battle_orchestrator.gd:925` 行内字符串 `"完美排雷!清图奖励 ×2"` → `"完美封印!清图奖励 ×2"` +- [ ] `game/presentation/views/board_fx_view.gd:102` `_show_banner("完美排雷 ×2")` → `_show_banner("完美封印 ×2")` +- [ ] `game/presentation/views/battle_log_view.gd:194` 按两态改写(见 T7,判据修正后语义才成立;此处只落文本占位,不留「已破」字样在豁免态) +- [ ] 其余 13 处(11 处代码注释/文档注释 + smoke_all.gd:3512/3516/4076 断言描述 + :6201 夹具期望字面量)逐处换代(清单见 §2 N1 表) - [ ] 跑 §2 末复现命令确认 `完美排雷` 零命中 **取用**:无。 @@ -193,12 +261,12 @@ ### T4 · 门票 → 专长凭证(注释面,≈1.0h) -- [ ] `game/core/adventure_runner.gd` 11 处注释换代(67/68/69/477/664/751/771/788/796/1033/1034) +- [ ] `game/core/adventure_runner.gd` 11 处注释换代(67/68/69/477/664/751/788/796/1033/1034) - [ ] `game/core/level_runner.gd` 4 处(51/781/826/831) - [ ] `game/data/schemas/adventure_table.gd` 3 处(92/96/97)+ `shop_table.gd:18` - [ ] `game/data/tables/shop.tres:104` 注释换代 - [ ] `game/presentation/curio_interact_controller.gd` 3 处(89/217/237)+ `curio_pick_overlay.gd:110` -- [ ] `game/smoke/level_autoplay.gd:226`+`smoke_all.gd` 8 处+`tests/**` 2 处换代 +- [ ] `smoke/level_autoplay.gd:226`+`smoke_all.gd` 8 处+`tests/**` 2 处换代 - [ ] 复核标识符与数据键零改动(`feat_ticket` 族、`"feat_ticket"` 行族键、存档键) **取用**:无。 @@ -218,7 +286,17 @@ **取用**:无。 **产出**:`game/` 内「落籍」零命中。 -### T7 · 全量验证与产出物落位(≈1.0h) +### T7 · N7 归因锚判据修正(≈1.5h) + +- [ ] 把 `core/settlement/grant_segment.gd:300` 的判据由 RAW 计数 `oc._perfect_hit_false == 1` 改为**有效误标**口径 `_perfect_hit_false - _perfect_forgiven == 1` +- [ ] 把豁免累加 `_perfect_forgiven += 1`(:314)上移到 `_emit_row`(:302)**之前**,使归因锚与谓词口径同源 +- [ ] 文案两态:未豁免 → `(本图完美封印已破——清图奖励不再加倍)`;已豁免 → `(首次封印落空已豁免——不计入完美封印判定)` +- [ ] 正向断言 A10/A11(见 §7) + +**取用**:T2 的对外文案换代结果。 +**产出**:日志文案与 `perfect_sweep_earned()` 真值一致(装备专长时豁免态不再出现「已破」)。 + +### T8 · 全量验证与产出物落位(≈1.0h) - [ ] 跑代码域档验收(按本批改动域选档),确认所选域全绿 - [ ] 确认回执 `game/tests/.gates/receipt.json` 的 commit = 分支 tip 且 `all_green=true` @@ -226,28 +304,32 @@ - [ ] 写 `reports/iter32-代拍板-<日期>.md` - [ ] 写 `reports/iter32-反哺点-<日期>.md`(§5 每条都要有落点) -**取用**:T1–T6 全部产出。 +**取用**:T1–T7 全部产出。 **产出**:`reports/` 三份产出物 + 可合回的分支 tip。 -**估时合计 ≈6.5–7.5h**(不含并行会话等待)。超 8h 切分预案:T3/T4 各拆「核心层」与「呈现+测试」两卡串行施工,其余不动。 +**估时合计 ≈8.5–10.0h**。切分预案(超 8h 即生效):T3/T4 各拆「核心层」与「呈现+测试」两卡串行施工;T7 独立成卡可单独验收,必要时可拆出本批另立缺陷批。 -## 7. 验证闸 +--- + +## 7 · 验证闸 ### 逐需求点验收清单 | # | 需求点 | 测什么(断言/行为) | 怎么测(落点) | 谁验 | |---|---|---|---|---| | A1 | N1 | `game/` 内 `完美排雷` 疑似现行计数 == 0 | grep 复现命令+同脚本口径 | 自动(S11+收尾 grep) | -| A2 | N1 | 对外文案三处文本恰为「完美封印…」,且不含「雷」字面 | 新冒烟断言:取清图高光行 `display_name`,断言 `find("雷") == -1` 且 `find("完美封印") >= 0`;落点 `game/smoke/smoke_all.gd` 清图段 | 自动(闸 01) | +| A2 | N1 | 对外文案三处文本恰为「完美封印…」,且不含「雷」字面 | 新冒烟断言:取清图高光行 `display_name`,断言 `find("雷") == -1` 且 `find("完美封印") >= 0`;落点 `game/smoke/smoke_all.gd` 清图段 | | A3 | N2 | `game/` 内 `板级` 计数 == 0 | 同 A1 | 自动 | -| A4 | N3 | `game/` 注释面 `门票` 计数 == 0;且 `feat_ticket` 标识符与存档键**保持原样** | 同 A1 + 新增断言:`grep -c "feat_ticket"` 计数 == 改前值 | 自动 | +| A4 | N3 | `game/` 注释面 `门票` 计数 == 0;且 `feat_ticket` 标识符与存档键**保持原样** | 同 A1 + 断言:`_feat_ticket_pity` 等标识符仍在位 | 自动 | | A5 | N4 | `game/` 内 `正主` 计数 == 0 | 同 A1 | 自动 | | A6 | N5 | `game/` 内 `落籍` 计数 == 0(历史注记行豁免) | 同 A1 | 自动 | -| A7 | N6 | S11 规则在位:注入禁用词 → 退出码 1 且输出含 `S11 FAIL`/命中行 | 注入实验(变异验证),落点 `game/tests/static_scan.sh` | 自动(人工执行一次取证) | +| A7 | N6 | S11 规则在位:注入禁用词 → 退出码 1 且输出含 `S11 FAIL`/命中行 | 注入实验,落点 `game/tests/static_scan.sh` | 自动(人工执行一次取证) | | A8 | 全域 | 冒烟绿数 == 基线 1151、单元 34 套全绿、探针段绿 | 跑所选域档 | 自动 | | A9 | 全域 | 回执 commit == 分支 tip 且 `all_green=true`,零新增红 | 跑闸后读 `game/tests/.gates/receipt.json` | 自动(合回闸) | +| **A10** | **N7** | **未装备完美保险:首次标错 → 日志出现「完美封印已破」,且 `perfect_sweep_earned() == false`** | 新增断言,落点 `tests/unit/core/feat_vouchers_test.gd`(现有专长套件) | 自动 | +| **A11** | **N7** | **装备完美保险:首次标错 → 日志出现豁免态文案,且不出现「已破」;`perfect_sweep_earned() == true`(加倍仍发)** | 同上 | 自动 | -**测试方式两分法**:A1–A7 属能力验证(静态扫描/断言直取数据)与取证实验;A8–A9 为运行期验证。玩家可见文案的最终观感归**用户目检**(登记不阻塞):商店/图例/HUD 与结算高光行读作「完美封印/封印印记」。 +**测试方式两分法**:A1–A7、A10–A11 属能力验证(静态扫描/断言直取数据)与取证实验;A8–A9 为运行期验证。玩家可见文案的最终观感归**用户目检**(登记不阻塞):结算明细中封印未中行的两态文案可读性。 **闸口径**:按本批改动域选档跑 `tools/run_all_gates.sh`(本批只触 `game/` 与 `reports/` → 代码域档);跑完写回执。 @@ -260,10 +342,14 @@ | `game/core/battle_orchestrator.gd:265` 注释 | 写回「板级完美排雷」原措辞 | `bash game/tests/static_scan.sh` | `S11 FAIL` + 命中行输出 | | 同上对外文案 | `game/core/battle_orchestrator.gd:925` 写回「完美排雷!…」 | 冒烟清图段 | 断言 A2 红 | | S11 扫描面 | 临时把 `DIR_CORE` 改成不存在目录 | `bash game/tests/static_scan.sh` | `S11 FAIL: 扫描面为空` | +| **N7 判据(反)** | 把 `grant_segment.gd:300` 改回 `_perfect_hit_false == 1`(RAW) | `tests/unit/core/feat_vouchers_test.gd` | 断言 A11 红(豁免态应无「已破」却出现) | +| **N7 判据(正)** | 把 :300 改成 `_perfect_hit_false - _perfect_forgiven <= 0`(恒真) | 同上 | 断言 A10 红(未豁免态应「已破」却缺失) | 注入后一律 `git checkout -- ` 精确还原,四件(变异点 file:行/跑的闸/红输出摘要/还原结论)记进实现报告变异验证记录表。 -## 8. 异常分级 +--- + +## 8 · 异常分级 - **L1(自救)**:单文件漏改致 grep 未过 → 补改重跑该段,不改批结构。 - **L2(记录继续)**:冒烟绿数与基线偏差 ≤2 且已归因到断言描述文本替换 → 记录偏差原因后继续。 @@ -272,25 +358,35 @@ 2. `.tres` 加载失败或 schema 不同步; 3. 改前改后同种子读数不一致; 4. S11 注入后不变红(判据无效); - 5. 触碰并行会话在改文件(`AGENTS.md`/`design/dev/code-conventions.md`)。 + 5. 触碰并行会话在改文件(`AGENTS.md`/`design/dev/code-conventions.md`); + 6. **N7 上移 `_perfect_forgiven` 累加后,奖励兑付结果与改前不一致**(说明改到了兑付行为,而非只改文案判据)。 -## 9. 代拍板白名单 +--- + +## 9 · 代拍板白名单 1. 注释换代时的措辞微调(如「板级变异」→「整图变异」vs「整图作用域变异」),语义等价即可。 2. `落籍`→`已入库` 在带 commit 号的历史注记行**不改**(留档文本)。 3. `正主` 误报处(`damage_math_test.gd:36`「正主角池」)不改。 4. 测试断言描述文本的替换措辞,语义等价即可。 5. S11 规则段的 shell 写法(grep 组合、计数方式),与现役 S 段同构即可。 +6. **N7 两态文案的末字微调**(保持「未豁免=已破、已豁免=不计入」这一因果不变成立即可)。 超清单必呈报。 -## 10. 待裁点 +--- + +## 10 · 待裁点 **零待裁点,开工门=U0(`/iter 32` 发令)。** -已落裁决两条,卡片据以成文: +已落裁决四条,卡片据以成文: | 裁定 | 结论 | |---|---| -| 完美排雷 | 全库统一换代为「完美封印」(含代码内部注释)——2026-10-19 用户裁;据此推翻 `需求卡片-凭证件裁削批`:108「内部开发用语按 v3.15 纪律保留」半句,卡片条款订正归文档轨批 | +| 完美排雷 | 全库统一换代为「完美封印」,含代码内部注释——2026-10-19 用户裁;据此推翻 `需求卡片-凭证件裁削批`:108「内部开发用语按 v3.15 纪律保留」半句,卡片条款订正归文档轨批 | +| 排雷(模块名) | **不扩大禁词面**。「排雷玩法/排雷规则」是内部机制名(=扫雷推理层的玩法动作总称,见 `00-游戏概念.md:5`),GDD 目录即 `systems/排雷循环/`,术语表正文在用,26 个文件保持原样 | | 门票 | 仅换代注释措辞;标识符与数据键零改动;玩家可见两处(`shop.tres:86`/`curio_interact_controller.gd:165-166`)移交文档侧定性 | +| 归因锚判据(N7) | 并入本批:`grant_segment.gd:300` 改用有效误标口径(总数 − 豁免数),豁免累加上移到 `_emit_row` 之前;文案按两态改写——2026-10-20 用户裁 | + +**禁用词机检闸不扩到 `game/`**(用户裁:代码与文档分开管理);代码侧改用代码域自己的静态扫描闸 S11,词表从 `design/gdd/术语表.md` 解析,不内联第二份。 From 0da014d4f12f023171cc80c00cdd36e7f37358f4 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 02:34:59 +0800 Subject: [PATCH 05/59] =?UTF-8?q?docs(roadmap):=20=E8=BF=AD=E4=BB=A3=2032?= =?UTF-8?q?=20=E7=BC=96=E6=8E=92=E2=80=94=E2=80=94=E5=8D=A1=E2=91=A0?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=B3=A8=E9=87=8A=E7=A6=81=E7=94=A8=E8=AF=8D?= =?UTF-8?q?=E6=B8=85=E6=89=AB=E6=89=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iter-plan 编排四查全过: ① 卡片文件存在:design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md 在盘(v1.1) ② 设计闭合凭据齐:06 条目设计面=工程直入 → 现状含代码级证据指认 (全量扫描读数 195 文件/逐词计数/file:line 落点/根因/上游裁定) ③ 总估时 ≈8.5–10.0h ≈ ≈0.5 周 ≤ 2 周 ④ 流水线闸 PASS roadmap 迭代总表增一行(六列): | 迭代 32 | 待开工 | design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md | 2026-10-20 | ≈0.5 周 | — | 顶部「当前位」三行换代:迭代位 1–31 已完成或已终止,迭代 32 待开工; 下一步=迭代 32 开工令(U0)归用户发。 06 条目状态推进:已写卡(卡片路径)→ +已编迭代 32。 --- design/gdd/06-待办清单.md | 2 +- roadmap.md | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index daf71dbb..906a2c48 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -692,4 +692,4 @@ **归属**:game/ 代码与数据表(代码域,走独立 worktree 批;并行避让——`changelog-retire-20261019` 在盘未合回且正在改 `AGENTS.md` 与 `design/dev/code-conventions.md`,本批禁碰这两个文件,S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`) -**状态**:已写卡(design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md) +**状态**:已写卡(design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md)+已编迭代 32 diff --git a/roadmap.md b/roadmap.md index 6171cf7b..c525d0b2 100644 --- a/roadmap.md +++ b/roadmap.md @@ -5,8 +5,8 @@ ## 当前位(只回答「现在该做什么」;三行内随批次换代,禁止在此扩写成状态快照) - **阶段**:M3——Alpha 版本的完整实现(2026-10-09 立规:未明令宣布完成前停留 M3,迭代只排 M3 需求,M4 不排期;根目录 stage.txt 为旧阶段开关仅存档)。 -- **迭代位**:迭代 1–30 全部已完成或已终止;**迭代 31 待开工**(两卡串行:卡①代码术语刷新批+卡②凭证件裁削批·代码侧,均 2026-10-18 编入)。 -- **下一步**:迭代 31 开工令(U0)归用户发。其余候选在 06 状态列——营地交互重做五卡(已写卡待编迭代)、迭代 30 原卡②③(待美术/设计定稿后重新立卡)。 +- **迭代位**:迭代 1–31 全部已完成或已终止;**迭代 32 待开工**(卡①代码注释禁用词清扫批,2026-10-20 编入)。 +- **下一步**:迭代 32 开工令(U0)归用户发。其余候选在 06 状态列——营地交互重做五卡(已写卡待编迭代)、冒险前资源配比预设(备选)、迭代 30 原卡②③(待美术/设计定稿后重新立卡)。 ## 里程碑时间线 @@ -65,6 +65,7 @@ | 迭代 29 | 已完成(2026-10-16) | design/research/需求卡片-测试分层与门禁语义修正批-2026-10-15.md | 2026-10-16 | — | reports/iter29-实现报告-2026-10-16.md | | 迭代 30 | 已完成(2026-10-17) | design/research/需求卡片-未开格类型徽章批-2026-10-16.md | 2026-10-16 | — | reports/iter30-实现报告-2026-10-17.md | | 迭代 31 | 待开工 | design/research/需求卡片-代码术语刷新批-2026-10-18.md、design/research/需求卡片-凭证件裁削批-2026-10-18.md | 2026-10-18 | ≈1.5 周 | — | +| 迭代 32 | 待开工 | design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md | 2026-10-20 | ≈0.5 周 | — | - 历史行的「—」= 该列事实不可考:迭代 1~8 早于需求卡片制;编排时点与预计周期不再回溯,细节查 git 提交史。 - 「已退役(git 历史可考)」= 需求卡片或实现报告曾存在,已按「证据只留最新」退役;已完成迭代的实现报告列只填 reports/ 现存路径或本保留字,不填「—」。 From 869d00d678f249ac67425a743b75b038283e707d Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 03:32:59 +0800 Subject: [PATCH 06/59] =?UTF-8?q?docs(card):=20=E9=9C=80=E6=B1=82=E5=8D=A1?= =?UTF-8?q?=E7=89=87=20v1.2=E2=80=94=E2=80=94=E5=BC=80=E5=B7=A5=E5=89=8D?= =?UTF-8?q?=E8=87=AA=E6=9F=A5=EF=BC=8C=E9=92=89=E6=AD=BB=E5=9B=9B=E5=A4=84?= =?UTF-8?q?=E4=BC=9A=E5=8D=A1=E4=BD=8F=E6=96=BD=E5=B7=A5=E6=96=B9=E7=9A=84?= =?UTF-8?q?=E5=8F=A3=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 逐条自查「施工方会不会回头问」,查出并定死四处(另有两处笔误订正): **1. S11 词表范围与 §4「不做」自相矛盾(最严重)** 原 T1 写「词表=退役词对照 + 用语规范 A 表禁用列全部」,但 §4 已把 A 表词 (不得 14/报错 18/对标 1/若干 1/buff 22)列为「不做、待用户另裁」。 ⇒ 原写法会让 S11 一落闸就红 56 处,批末闸必然红、无法合回。 定死:词表=退役词对照节第一列 + 显式追加「完美排雷」完整短语; 明确不收 A 表词、不收单字「雷」。A 表将来裁入时另行扩表并单独立批。 **2. 单字「雷」会误伤 26 处保留词** 「排雷玩法/排雷规则」是内部机制名(§10 明定不扩大禁词面), 按单字「雷」扫会全部误判。定死:只收「完美排雷」完整短语。 **3. N7 修法不可行——_fx_emit 有状态,重复调用重复消费限次** _fx_emit = _fx.dispatch(battle_orchestrator.gd:90-93),forgive_seal_miss 行 走 when lt 1 限次并由 _apply_counter_hit 记账 ⇒ 「先跑一次算 hl 再跑原循环」 会消费两次限次、归因行发两次。 定死:改为把 _emit_row("seal_miss")(:302)**后移**到 _fx_emit 循环(:308-317)之后, 循环跑完 _perfect_forgiven 已就位再判 hl。已实测 grep "insurance_used|perfect_insurance" game/smoke/smoke_all.gd 零命中 ⇒ 行序调换不涉冒烟断言。 **4. A10/A11 断言落点不可执行** 原写「断言日志出现/不出现字样」,但日志文本由呈现层 battle_log_view._format_row 生成,core 层单测拿不到。定死:断言 seal_miss 行的 highlight 字段值 (未装备 == "perfect_broken"/装备 == ""),落点 tests/unit/core/; 另加 A12 断言两态文案与呈现分支一致且不含「雷」。 **另订正两处**:§4「做」列表重复第 6 项(完美排雷出现两次); T4 步骤 adventure_runner.gd 漏列 :771(写 11 处只列 10 个行号)。 **同步新增**:契约 9 S11 闸门自指豁免(smoke_all.gd:1319 的禁字面检查行与 ui_font_asset_test.gd:18-19 字形夹具不含对照性信号,会被自指判红); 变异验证增「去掉自指豁免」一条;代拍板/范围边界措辞同步。 处数对账复核:T3=26/T4=35/T5=11/T6=9,与 §2 清单一致。 流水线闸 PASS:06 条目 64 · 总表数据行 32 · 交叉核 3 链 · 卡片口径 22 张全过。 --- ...œ€求卡片-代码注释禁用词清扫批-2026-10-20.md | 51 +++++++++++-------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md b/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md index 5ea88db3..1168059c 100644 --- a/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md +++ b/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md @@ -4,7 +4,8 @@ - **日期**:2026-10-20 - **批次性质**:工程债/重构 + 缺陷修复(两类均属工程直入四类,凭 06 在册条目与代码级证据直接写卡) - **设计事实源**(唯一事实源:`design/gdd/术语表.md`「退役词对照」+「用语规范 A 表」+「对外命名纪律」节;`design/gdd/systems/战斗循环/战斗结算.md`「完美排雷」规则节;req-card 三选一之③工程直入证据指认):扫描读数=`game/` 下 195 个文件(.gd/.tres/.md/.json/.sh/.txt)逐处实测,落点带 file:line(见 §2);复现命令见 §2 末。 -- **版本**:**v1.1**(2026-10-20:grilling 复核门查出 N7 概念冲突,新增需求点与 T7 卡;T2 的对外文案由「机械换词」改为「按概念两态改写」) +- **版本**:**v1.2**(2026-10-20:开工前自检查出四处会卡住施工方的未定口径——S11 词表范围/「雷」字面误伤面/N7 修法可行性与限次重复消费/A10·A11 断言落点——全部钉死;T7 修法由「上移豁免」改为「后移 `_emit_row`」,已核实 `_fx_emit` 有状态不可重复调用) +- 历史:v1.1(2026-10-20:grilling 复核门查出 N7 概念冲突,新增需求点与 T7 卡;T2 的对外文案由「机械换词」改为「按概念两态改写」) - **迭代归属**:待编入 roadmap 迭代 32(本卡不自行编入;编排归 iter-plan 段) - **上游依据**:2026-10-19 用户裁——「完美排雷」**全库统一**换代为「完美封印」,含代码内部注释 @@ -54,7 +55,7 @@ 1. `game/` 内 `完美排雷`/`板级`/`门票`(注释面)/`正主`/`落籍` 五词,**疑似现行计数全部为 0**(豁免=含对照/历史信号的行)。 2. 对外文案三处不含「雷」字面,读作「完美封印」。 -3. **N7**:装备「完美保险」专长时本战首次标错 → 日志**不**出现「已破」字样,改出现豁免态文案;未装备时首次标错 → 出现「已破」态文案。两态各有正向断言。 +3. **N7**:装备「完美保险」专长时本战首次标错 → `seal_miss` 行的 `highlight` 字段为 `""`(豁免态,无金框),且 `perfect_sweep_earned() == true`;未装备时首次标错 → `highlight` 为 `"perfect_broken"`(已破态,金框),且 `perfect_sweep_earned() == false`。两态各有正向断言(A10/A11)。 4. 冒烟绿数与改前基线一致(现行 1151 项 0 失败)、单元测试 34 套全绿、探针段绿。 5. S11 规则在位:注入一次禁用词 → `game/tests/static_scan.sh` 判红;还原后绿;变异验证记录进实现报告。 6. 代码域闸按域选档跑通,回执 `game/tests/.gates/receipt.json` 的 commit = 分支 tip 且 `all_green=true`。 @@ -139,8 +140,9 @@ 4. 🔴 **完美封印判据单点**——「是否已破」只允许由 `battle_orchestrator.perfect_sweep_earned()` 的有效误标口径派生,禁在 `grant_segment.gd` 另立 RAW 计数判据;两处口径不一致即为缺陷。 5. 🔴 **游戏行为零变化**(N1–N5、N7 判据修正前)——纯中文文本替换,禁止改动逻辑、数值、权重、条件判断。N7 判据修正是**本批唯一允许的逻辑改动**,其验收为「日志文案与真值一致」,不改奖励兑付结果。 6. 🔴 **S11 规则先落、后修码**——先把规则写进 `game/tests/static_scan.sh` 并跑出红,再动注释(code-conventions 缺陷-规范对照表纪律)。 -7. 🔴 **S11 词表不内联第二份**——规则脚本从 `design/gdd/术语表.md`(「退役词对照」+「用语规范 A 表」两节)解析词面;禁止在脚本里另抄一份词表(单一事实源红线,ADR 漂移教训同类)。 -8. 🔴 **S11 必须带扫描面零命中自检**——先数一遍扫描面文件数,为零即判红(沿 S3 教训:路径写歪时自检一起歪、一起红,不会静默恒绿)。 +7. 🔴 **S11 词表范围=本批清理范围,且从术语表解析不内联**——词表面=`design/gdd/术语表.md`「退役词对照」节第一列全部词面(去括号注),**显式追加 `完美排雷` 完整短语**(该词受「对外命名纪律」约束,不在退役词对照表里,故需显式列入)。**明确不收**:①术语表「用语规范」A 表词面(`不得`/`报错`/`对标`/`若干`/`buff`)——§4 已列「不做」,收进来批末必然红;②单字「雷」——会误伤 26 处保留词「排雷玩法/排雷规则」(内部机制名,§10 明定不扩大禁词面)。**禁止在脚本里另抄一份词表**(单一事实源红线,ADR 漂移教训同类)。A 表词将来若被裁决纳入,另行扩词表并单独立批清扫。 +8. 🔴 **S11 必须带两道零命中自检**——①扫描面文件数为零即判红;②从术语表解析出的词面数为零即判红(沿 S3 教训:路径写歪或表格结构变了时,自检一起歪、一起红,不会静默恒绿)。 +9. 🔴 **S11 闸门自指豁免**——命中行若属「检查禁用词本身」的闸门形态(行内含 `contains(`/`find(`/`grep`/`has_char(`/`禁「`/`禁『`/`零「`/`零『` 等检查或禁令表述),或含 `doc_term_audit.py` 同源的对照/历史信号,一律豁免、不判红。现存受此豁免的两处:`game/smoke/smoke_all.gd:1319`(禁字面检查逻辑)与 `game/tests/unit/presentation/ui_font_asset_test.gd:18`/`:19`(字形覆盖夹具)。 9. 🔴 **禁碰并行会话在改的文件**——`AGENTS.md` 与 `design/dev/code-conventions.md`(分支 `changelog-retire-20261019` 在盘未合回)。S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`。 10. 🔴 **对照性文本豁免**——含退役/更名/禁令等信号的行不改写(术语表用语规范 B 类豁免条款)。 @@ -155,11 +157,10 @@ 3. `game/` 内注释面 `门票`→`专长凭证`(35 处,剔除移交 3 处) 4. `game/` 内注释面 `正主`→`现行事实源`(11 处,剔除误报 1 处) 5. `game/` 内注释面 `落籍`→`已入库`(9 处,剔除历史注记 1 处) -6. `game/` 内 `完美排雷`→`完美封印`(16 处) -7. **N7**:封印未中行归因锚改用有效误标判据,文案按两态改写 -8. 代码域静态扫描闸新增 S11 规则(含零命中自检) -9. `game/README.md`/`game/tests/README.md` 同步 -10. 全量冒烟+单元+探针验证,绿数与基线一致 +6. **N7**:封印未中行归因锚改用有效误标判据,文案按两态改写 +7. 代码域静态扫描闸新增 S11 规则(词表=退役词对照+`完美排雷`;含两道零命中自检与闸门自指豁免) +8. `game/README.md`/`game/tests/README.md` 同步 +9. 全量冒烟+单元+探针验证,绿数与基线一致 **不做**(去向): @@ -225,13 +226,17 @@ ### T1 · S11 规则落闸并见红(≈1.0–1.5h) -- [ ] 在 `game/tests/static_scan.sh` 头部注释补 S11 一行说明(规则名+权威出处+扫描面) +- [ ] 在 `game/tests/static_scan.sh` 头部注释补 S11 一行说明(规则名+权威出处+扫描面+词表来源) - [ ] 新增 S11 段:扫描面=`game/` 全域(.gd/.tres/.md/.json),与迭代 31 V4 判据同口径 - [ ] 逐行取注释文本段(`#`/`;` 前缀),剔除含对照/历史信号的行 -- [ ] 词表面从 `design/gdd/术语表.md` 解析:「退役词对照」表第一列全部词面(去括号注)+「用语规范」A 表「禁用」列全部词面 -- [ ] 规则先数扫描面文件数,为零即 `echo "[static_scan] S11 FAIL: 扫描面为空"` 并 `fail=1` +- [ ] 词表面从 `design/gdd/术语表.md`「退役词对照」节解析第一列全部词面(去括号注),**显式追加 `完美排雷` 完整短语**;不收 A 表词、不收单字「雷」(契约 7) +- [ ] 命中行先过闸门自指豁免(行内含 `contains(`/`find(`/`grep`/`has_char(`/`禁「`/`禁『`/`零「`/`零『` 即跳过),再判红(契约 9) +- [ ] 自检一:扫描面文件数为零即 `echo "[static_scan] S11 FAIL: 扫描面为空"` 并 `fail=1` +- [ ] 自检二:解析出的词面数为零即 `echo "[static_scan] S11 FAIL: 词表解析为空"` 并 `fail=1` - [ ] 命中即打印 `file:line + 命中词`,段末 `fail=1` +- [ ] 在 `game/tests/README.md` 的静态扫描登记处补 S11 一行(规则名/扫描面/词表来源/豁免条款) - [ ] 注入验证:在 `game/core/battle_orchestrator.gd` 某注释里临时写回「板级」一词 → 跑 `bash game/tests/static_scan.sh` 见红并记输出摘要 → `git checkout -- game/core/battle_orchestrator.gd` 精确还原 → 记录进实现报告变异验证表 +- [ ] 反向验证:在 `game/smoke/smoke_all.gd:1319`(禁字面检查行)写回原句 → 跑闸**仍为绿**(验证自指豁免生效)→ 还原 **取用**:无。 **产出**:`game/tests/static_scan.sh` 的 `S11` 段(退出码语义=任一硬失败规则命中即 `exit 1`,与现役同段同规)。 @@ -261,7 +266,7 @@ ### T4 · 门票 → 专长凭证(注释面,≈1.0h) -- [ ] `game/core/adventure_runner.gd` 11 处注释换代(67/68/69/477/664/751/788/796/1033/1034) +- [ ] `game/core/adventure_runner.gd` 11 处注释换代(67/68/69/477/664/751/771/788/796/1033/1034) - [ ] `game/core/level_runner.gd` 4 处(51/781/826/831) - [ ] `game/data/schemas/adventure_table.gd` 3 处(92/96/97)+ `shop_table.gd:18` - [ ] `game/data/tables/shop.tres:104` 注释换代 @@ -288,9 +293,13 @@ ### T7 · N7 归因锚判据修正(≈1.5h) -- [ ] 把 `core/settlement/grant_segment.gd:300` 的判据由 RAW 计数 `oc._perfect_hit_false == 1` 改为**有效误标**口径 `_perfect_hit_false - _perfect_forgiven == 1` -- [ ] 把豁免累加 `_perfect_forgiven += 1`(:314)上移到 `_emit_row`(:302)**之前**,使归因锚与谓词口径同源 -- [ ] 文案两态:未豁免 → `(本图完美封印已破——清图奖励不再加倍)`;已豁免 → `(首次封印落空已豁免——不计入完美封印判定)` +**修法(已核实可行,禁另选他法)**:`_fx_emit`(`battle_orchestrator.gd:90-93`)是 `_fx.dispatch` 的**有状态派发**——`forgive_seal_miss` 行走 `when lt 1` 限次并由 `_apply_counter_hit` 记账,**重复调用会重复消费限次**。因此**禁止**"先跑一次 `_fx_emit` 算 `hl` 再在原位置跑一次"的做法。 + +- [ ] 把 `core/settlement/grant_segment.gd:302` 的 `oc._emit_row("seal_miss", ...)` **后移**到 `for h in oc._fx_emit("seal_missed", ...)` 循环(:308-317)**之后**——循环结束后 `_perfect_forgiven` 已就位,判据才有真值可用 +- [ ] 判据改有效误标:`var hl := "perfect_broken" if oc._perfect_hit_false - oc._perfect_forgiven == 1 else ""`(替代原 :300 的 RAW 计数 `oc._perfect_hit_false == 1`) +- [ ] 确认行序调换的零影响:`grep -n "insurance_used\|perfect_insurance" game/smoke/smoke_all.gd` 已实测**零命中**——冒烟未断言这两行的相对顺序,调换不涉断言 +- [ ] 文案两态:未豁免(`hl == "perfect_broken"`)→ `(本图完美封印已破——清图奖励不再加倍)`;已豁免(`hl == ""`)→ `(首次封印落空已豁免——不计入完美封印判定)` +- [ ] 豁免态**不加金框**——`hl == ""` 时 `battle_log_view.gd:195` 走普通色分支;金框语义=强调负面事件,豁免是正向事件,靠同批已存在的 `insurance_used` 行(:316-317)承载反馈即可。不新增高光标记 - [ ] 正向断言 A10/A11(见 §7) **取用**:T2 的对外文案换代结果。 @@ -326,8 +335,9 @@ | A7 | N6 | S11 规则在位:注入禁用词 → 退出码 1 且输出含 `S11 FAIL`/命中行 | 注入实验,落点 `game/tests/static_scan.sh` | 自动(人工执行一次取证) | | A8 | 全域 | 冒烟绿数 == 基线 1151、单元 34 套全绿、探针段绿 | 跑所选域档 | 自动 | | A9 | 全域 | 回执 commit == 分支 tip 且 `all_green=true`,零新增红 | 跑闸后读 `game/tests/.gates/receipt.json` | 自动(合回闸) | -| **A10** | **N7** | **未装备完美保险:首次标错 → 日志出现「完美封印已破」,且 `perfect_sweep_earned() == false`** | 新增断言,落点 `tests/unit/core/feat_vouchers_test.gd`(现有专长套件) | 自动 | -| **A11** | **N7** | **装备完美保险:首次标错 → 日志出现豁免态文案,且不出现「已破」;`perfect_sweep_earned() == true`(加倍仍发)** | 同上 | 自动 | +| **A10** | **N7** | **未装备完美保险:本战首次标错 → `seal_miss` 行的 `highlight` 字段 == `"perfect_broken"`,且 `perfect_sweep_earned() == false`** | 新增断言,落点 `tests/unit/core/feat_vouchers_test.gd`(现有专长套件,core 层可直取行字段) | 自动 | +| **A11** | **N7** | **装备完美保险:本战首次标错 → `seal_miss` 行的 `highlight` 字段 == `""`,且 `perfect_sweep_earned() == true`(加倍仍发)** | 同上 | 自动 | +| **A12** | **N7** | 两态文案常量与 `battle_log_view.gd` 呈现一致:`_format_row` 对 `hl=="perfect_broken"` 输出「已破」态、对 `hl==""` 输出豁免态,两态均不含「雷」字面 | 断言落点 `tests/unit/core/feat_vouchers_test.gd`(取行字段后按同一分支规则格式化比对) | 自动 | **测试方式两分法**:A1–A7、A10–A11 属能力验证(静态扫描/断言直取数据)与取证实验;A8–A9 为运行期验证。玩家可见文案的最终观感归**用户目检**(登记不阻塞):结算明细中封印未中行的两态文案可读性。 @@ -342,8 +352,9 @@ | `game/core/battle_orchestrator.gd:265` 注释 | 写回「板级完美排雷」原措辞 | `bash game/tests/static_scan.sh` | `S11 FAIL` + 命中行输出 | | 同上对外文案 | `game/core/battle_orchestrator.gd:925` 写回「完美排雷!…」 | 冒烟清图段 | 断言 A2 红 | | S11 扫描面 | 临时把 `DIR_CORE` 改成不存在目录 | `bash game/tests/static_scan.sh` | `S11 FAIL: 扫描面为空` | -| **N7 判据(反)** | 把 `grant_segment.gd:300` 改回 `_perfect_hit_false == 1`(RAW) | `tests/unit/core/feat_vouchers_test.gd` | 断言 A11 红(豁免态应无「已破」却出现) | -| **N7 判据(正)** | 把 :300 改成 `_perfect_hit_false - _perfect_forgiven <= 0`(恒真) | 同上 | 断言 A10 红(未豁免态应「已破」却缺失) | +| **N7 判据(反)** | `grant_segment.gd` 判据改回 `_perfect_hit_false == 1`(RAW 计数) | `tests/unit/core/feat_vouchers_test.gd` | 断言 A11 红(装备专长时 `highlight` 应为 `""` 却得 `"perfect_broken"`) | +| **N7 判据(正)** | 判据改成 `_perfect_hit_false + _perfect_forgiven == 1`(符号写反) | 同上 | 断言 A10 红(未装备专长时 `highlight` 应为 `"perfect_broken"` 却得 `""`) | +| **S11 自指豁免** | 去掉 S11 的闸门自指豁免分支 | `bash game/tests/static_scan.sh` | `smoke_all.gd:1319` 与 `ui_font_asset_test.gd:18` 判红 | 注入后一律 `git checkout -- ` 精确还原,四件(变异点 file:行/跑的闸/红输出摘要/还原结论)记进实现报告变异验证记录表。 From a082f8a4fd1570c6fe922df21448190bce5c9196 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 04:08:52 +0800 Subject: [PATCH 07/59] =?UTF-8?q?docs(card):=20=E9=9C=80=E6=B1=82=E5=8D=A1?= =?UTF-8?q?=E7=89=87=20v1.3=E2=80=94=E2=80=94=E4=BA=8C=E8=BD=AE=E5=BC=80?= =?UTF-8?q?=E5=B7=A5=E5=89=8D=E8=87=AA=E6=9F=A5=EF=BC=8C=E4=BA=94=E5=A4=84?= =?UTF-8?q?=E6=89=B9=E6=9C=AB=E9=AA=8C=E6=94=B6=E9=9B=B7=E5=85=A8=E9=83=A8?= =?UTF-8?q?=E6=8B=86=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 回应用户「是否还有需裁断项」的全量审计(五词原始命中 119 行逐处实测): 1. S11 词表若收「退役词对照」首列全词 → 巢穴 20 处(玩家专名「巢穴 预告」+风味层)与旗 6 处(闸门自指 5+更名记载 1)批末必红 → 立显式排除单(巢穴/旗,理由:术语表风味层除外注+B3 专名豁免+ doc_term_audit 既有判例「旗单字不入表」)。 2. enemy.tres:653 落籍留档不被旧 25 子串信号过滤豁免 → 批末 S11+A6 必红;且该过滤实测误伤 14/17 处活注释(→/历史/登记/豁免等子串 误判)→ 废信号过滤,改显式留档豁免单 4 处+显式待清清单。 3. 误伤的 14 处活注释补入清单:N1 16→21、N2 26→33(hud_presenter/ ui_input_probe 两文件整文件旧漏)、N3 38→39、N4 12→14;T2/T3/T4/T5 任务清单与 §4 计数同步(复算对拍:待清 21+33+36+13+9=112)。 4. T7 行序调换+hl 两态化会漂移 parity JSONL(_on_step_row 逐行落盘 含 highlight,11 号闸 sha256 逐位比对)→ 立契约 12:本批不发起 parity(NEED-APPROVAL 态 all_green 不受影响)、漂移记档、合回后另立 用户批准的重锚批;N7 验收走 A10/A11/A12 正向断言(纪律①主力)。 5. A2 补 board_fx_view.gd:102 静态覆盖(S11 只扫注释面,字符串字面量 归断言面);S11 扫描面补 .sh;规则说明立禁令引举句式(否则闸本体 头注被自己判红)。 另订正:§10/§8 旧修法措辞(上移豁免→后移 _emit_row)、契约编号去重 (原两个 9)、N1 表内计数、06 条目同步(含修其自指引爆的 doc_term 红——bash tools/run_all_gates.sh --docs 复跑全绿)。 --- design/gdd/06-待办清单.md | 12 +- ...œ€求卡片-代码注释禁用词清扫批-2026-10-20.md | 141 +++++++++++------- 2 files changed, 91 insertions(+), 62 deletions(-) diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index 906a2c48..beaab58f 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -680,16 +680,16 @@ #### 代码注释禁用词清扫批——退役词换代+完美封印统一+归因锚判据修正(2026-10-20 登记,来源=会话提及,设计面=工程直入) -**现状**:2026-10-19 全量扫描 `game/`(195 个文件:.gd/.tres/.md/.json/.sh/.txt)的可复核实测读数,口径=剔除含对照性/历史信号的行后计「疑似现行残留」。 -**确定违规**(术语表「退役词对照」在册,落于代码注释面)=`板级` 26 处/`门票` 38 处/`正主` 12 处(含 `tests/unit/battle_settlement/damage_math_test.gd:36`「正主角池」误报 1 处)/`落籍` 10 处(含 `data/tables/enemy.tres:653` 带 commit 号的历史注记 1 处,不追改)。 -**含「雷」字面**(违反术语表「对外命名纪律」——「雷」及相关字面禁入对外命名,适用范围含 UI 文案)=`完美排雷` 16 处,其中 **3 处为玩家可见文案**:`core/battle_orchestrator.gd:925` `"完美排雷!清图奖励 ×2"`、`presentation/views/board_fx_view.gd:102` `_show_banner("完美排雷 ×2")`、`presentation/views/battle_log_view.gd:194` `"(本板完美排雷已破——归因此封印)"`(末条 `design/qa/文案审查报告-2026-10-18.md:150` 已判病句,至今未修)。 +**现状**:2026-10-19 全量扫描 `game/`(195 个文件:.gd/.tres/.md/.json/.sh/.txt)的可复核实测读数;v1.3(2026-10-20)全量复核后口径订正=**命中行全部计入待清,显式豁免仅限 4 处**(`enemy.tres:653` 落籍留档/`level_runner.gd:832` 门票历史注记/`adventure_runner.gd:403` 正主历史修复注记/`damage_math_test.gd:36` 正主误报)——旧「信号子串过滤」实测误伤 14/17 处活注释且漏豁免 653,已废。 +**确定违规**(术语表「退役词对照」在册,落于代码注释面)=`板级` 33 处/`门票` 39 处(含移交 3 处,本批做 36)/`正主` 14 处(含误报与历史注记各 1 处,本批做 13)/`落籍` 10 处(含 `data/tables/enemy.tres:653` 带 commit 号的历史注记 1 处,不追改;本批做 9)。 +**含「雷」字面**(违反术语表「对外命名纪律」——「雷」及相关字面禁入对外命名,适用范围含 UI 文案)=`完美排雷` 21 处,其中 **3 处为玩家可见文案**:`core/battle_orchestrator.gd:925` `"完美排雷!清图奖励 ×2"`、`presentation/views/board_fx_view.gd:102` `_show_banner("完美排雷 ×2")`、`presentation/views/battle_log_view.gd:194` `"(本板完美排雷已破——归因此封印)"`(末条 `design/qa/文案审查报告-2026-10-18.md:150` 已判病句,至今未修)。 **根因**:迭代 31 卡① 完成判据 V4 只覆盖「金币/插旗/雷格/惩罚格」四词(+旗族),`排雷`/`雷`族未入完成判据;且机检闸 `tools/doc_term_audit.py` 的 `DEFAULT_DIRS = ["design/gdd"]`,**代码注释面从未进闸**——不清根则同类残留持续复发。 **裁定(2026-10-19 用户)**:完美排雷**全库统一**换代为「完美封印」,含代码内部注释。本裁**推翻** `需求卡片-凭证件裁削批`:108「内部开发用语按 v3.15 纪律保留」半句,该卡片条款订正归**文档轨批**,代码批照本裁执行。 **移交(不属本批)**:`game/data/tables/shop.tres:86` display_name「奇物门票」、`game/presentation/curio_interact_controller.gd:165-166`「开一次奇物三选一」——两处属 奇物/专长 归类表述,与 06「2026-10-18 冒记案遗留待裁两项」第①项同源,交文档侧先定性,定后另走传导批。 -**扫描中查出的真缺陷(N7)**:`core/settlement/grant_segment.gd:300` 用 RAW 误标计数判「完美封印已破」,而 `core/battle_orchestrator.gd:1299` 的真正谓词用**有效误标**(总数 − 豁免数);且豁免累加(:314)排在 `_emit_row`(:302)之后。⇒ 装备「完美保险」时日志打印「已破」,实际加倍奖励仍发,日志与真值矛盾。2026-10-20 用户裁=并入本批修(判据改有效误标+豁免上移+文案两态)。 +**扫描中查出的真缺陷(N7)**:`core/settlement/grant_segment.gd:300` 用 RAW 误标计数判「完美封印已破」,而 `core/battle_orchestrator.gd:1299` 的真正谓词用**有效误标**(总数 − 豁免数);且豁免累加(:314)排在 `_emit_row`(:302)之后。⇒ 装备「完美保险」时日志打印「已破」,实际加倍奖励仍发,日志与真值矛盾。2026-10-20 用户裁=并入本批修(判据改有效误标+`_emit_row` 后移至豁免循环之后+文案两态;修法 v1.2 定型——上移豁免累加需重复调用 `_fx_emit` 会重复消费限次,已核实不可行)。 -**不做(待用户另裁)**:术语表 A 表词(`不得` 14/`报错` 18/`对标` 1/`若干` 1/`buff` 22——后者绝大多数是标识符与数据键)、doc-conventions 第 4 节流程动词(`收口` 128/`随批` 20/`台账` 17/`对拍` 16/`在飞` 10/`落文` 2)、简明技术中文(STC)通用禁用词(`缺省` 105/`情况` 26/`入参|出参` 23/`比较|较为|相对` 22 等)。 +**不做(待用户另裁)**:术语表 A 表词一族、doc-conventions 第 4 节流程动词一族、简明技术中文(STC)通用禁用词一族——三族的逐词计数与清单见卡片 §4「不做」表(本行不复制词面:06 正文引述禁词会自指引爆 doc_term 补充通道,判红)。 **归属**:game/ 代码与数据表(代码域,走独立 worktree 批;并行避让——`changelog-retire-20261019` 在盘未合回且正在改 `AGENTS.md` 与 `design/dev/code-conventions.md`,本批禁碰这两个文件,S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`) -**状态**:已写卡(design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md)+已编迭代 32 +**状态**:已写卡(design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md,**v1.3**)+已编迭代 32 diff --git a/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md b/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md index 1168059c..483b9b68 100644 --- a/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md +++ b/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md @@ -4,9 +4,10 @@ - **日期**:2026-10-20 - **批次性质**:工程债/重构 + 缺陷修复(两类均属工程直入四类,凭 06 在册条目与代码级证据直接写卡) - **设计事实源**(唯一事实源:`design/gdd/术语表.md`「退役词对照」+「用语规范 A 表」+「对外命名纪律」节;`design/gdd/systems/战斗循环/战斗结算.md`「完美排雷」规则节;req-card 三选一之③工程直入证据指认):扫描读数=`game/` 下 195 个文件(.gd/.tres/.md/.json/.sh/.txt)逐处实测,落点带 file:line(见 §2);复现命令见 §2 末。 -- **版本**:**v1.2**(2026-10-20:开工前自检查出四处会卡住施工方的未定口径——S11 词表范围/「雷」字面误伤面/N7 修法可行性与限次重复消费/A10·A11 断言落点——全部钉死;T7 修法由「上移豁免」改为「后移 `_emit_row`」,已核实 `_fx_emit` 有状态不可重复调用) +- **版本**:**v1.3**(2026-10-20:二轮开工前自查(回应用户「是否还有需裁断项」)——五词全量审计 119 行命中,查出五处会卡住批末验收的问题全部钉死:①S11 词表若收「退役词对照」首列全词,巢穴 20 处(玩家专名+风味层)与旗 6 处(闸门自指+更名记载)批末必红 → 立显式排除单;②`enemy.tres:653` 落籍留档不被旧信号过滤豁免 → 批末 S11+A6 必红 → 废 25 子串信号过滤(实测误伤 14/17 处活注释),改显式留档豁免单 4 处;③误伤的 14 处活注释补入显式待清清单(N1 16→21、N2 26→33、N3 38→39、N4 12→13/14);④T7 行序调换+`hl` 两态化会漂移 parity JSONL(`_on_step_row` 逐行落盘含 `highlight`,11 号闸按 sha256 逐位比对)→ 立契约 11:本批不发起 parity、漂移记档、合回后另立用户批准的重锚批;⑤A2 补 `board_fx_view.gd:102` 静态覆盖(S11 只扫注释面,字符串字面量归断言面)。另订正 §10/§8 旧修法措辞(上移豁免→后移 `_emit_row`)与 N1 表内计数) +- 历史:v1.2(2026-10-20:开工前自检查出四处会卡住施工方的未定口径——S11 词表范围/「雷」字面误伤面/N7 修法可行性与限次重复消费/A10·A11 断言落点——全部钉死;T7 修法由「上移豁免」改为「后移 `_emit_row`」,已核实 `_fx_emit` 有状态不可重复调用) - 历史:v1.1(2026-10-20:grilling 复核门查出 N7 概念冲突,新增需求点与 T7 卡;T2 的对外文案由「机械换词」改为「按概念两态改写」) -- **迭代归属**:待编入 roadmap 迭代 32(本卡不自行编入;编排归 iter-plan 段) +- **迭代归属**:**已编入 roadmap 迭代 32**(`0da014d4`,周期列 ≈0.5 周;开工门=U0 `/iter 32` 用户发令) - **上游依据**:2026-10-19 用户裁——「完美排雷」**全库统一**换代为「完美封印」,含代码内部注释 --- @@ -43,7 +44,7 @@ | 需求点 | 一句话 | |---|---| -| **N1** | 「完美排雷」全库统一为「完美封印」(对外文案 3 处 / 代码注释与内部文档 13 处) | +| **N1** | 「完美排雷」全库统一为「完美封印」(对外文案 3 处 / 其余 18 处:注释、文档正文、断言描述与夹具) | | **N2** | 注释里「板级」换代为「整图」 | | **N3** | 注释里「门票」换代为「专长凭证」(标识符与数据键零改动) | | **N4** | 注释里「正主」换代为「现行事实源」 | @@ -53,7 +54,7 @@ **完成定义**(全部满足才算完): -1. `game/` 内 `完美排雷`/`板级`/`门票`(注释面)/`正主`/`落籍` 五词,**疑似现行计数全部为 0**(豁免=含对照/历史信号的行)。 +1. `game/` 内 `完美排雷`/`板级`/`门票`(注释面)/`正主`/`落籍` 五词,**改后命中行 == §2 显式豁免单(4 处)+移交 3 处,其余为零**(v1.3 起口径=全部命中计入待清、显式豁免逐处列举;移交行非注释面,S11 与 A4 的注释面口径天然不含)。 2. 对外文案三处不含「雷」字面,读作「完美封印」。 3. **N7**:装备「完美保险」专长时本战首次标错 → `seal_miss` 行的 `highlight` 字段为 `""`(豁免态,无金框),且 `perfect_sweep_earned() == true`;未装备时首次标错 → `highlight` 为 `"perfect_broken"`(已破态,金框),且 `perfect_sweep_earned() == false`。两态各有正向断言(A10/A11)。 4. 冒烟绿数与改前基线一致(现行 1151 项 0 失败)、单元测试 34 套全绿、探针段绿。 @@ -65,12 +66,22 @@ --- -## 2 · 现状事实(2026-10-19 实测,开工自行复核) +## 2 · 现状事实(2026-10-19 实测;v1.3 于 2026-10-20 全量复核——五词原始命中 119 行,开工自行复核) 扫描范围:`game/` 下 195 个文件(.gd/.tres/.md/.json/.sh/.txt)。 -口径:命中行若含对照性/历史信号(`退役`/`作废`/`换装`/`继任`/`留档`/`历史`/`已删`/`不再`/`禁用`/`禁「`/`字面`/`原「`/`旧称`/`更名`/`换代`/`改为`/`→`/`禁令`/`引举`/`对照`/`豁免`/`待裁`/`已入库`/`登记`/`风味`)则不计入。 -### N1 · 完美排雷(16 处 / 9 文件) +**口径(v1.3 重订——废 25 子串信号过滤,改显式豁免单)**:命中行**全部计入待清清单**;显式豁免仅限下列 4 处(逐处列举理由)。v1.2 及以前用的信号子串过滤(`退役`/`作废`/`→`/`历史`/`登记`/`豁免` 等 25 个)实测**误伤 14/17 处活注释**(行内只是行文带了 `→` 或别处主语含「豁免/作废」就被当对照行跳过),且**漏豁免** `enemy.tres:653`(批末 S11+A6 必红)——两面都不靠谱,故废。 + +| 豁免行 | 词 | 理由 | +|---|---|---| +| `game/data/tables/enemy.tres:653` | 落籍 | 带 commit 号(9cc4b8b)的落表留档注记——B1 历史文本(代拍板白名单 2 已裁不改) | +| `game/core/level_runner.gd:832` | 门票 | 迭代 12 T6「渠道分离退役」的历史注记——B1 历史文本 | +| `game/core/adventure_runner.gd:403` | 正主 | T4 F-1 历史修复注记(行内主语=已退役写口 `_attune_refresh_x`;且此处「正主」义为缺陷根因而非权威源,换代反毁句意) | +| `game/tests/unit/battle_settlement/damage_math_test.gd:36` | 正主 | 误报——「正主角池」=正主+角池,非词面命中 | + +**移交 3 处**(不属本批,去向=文档轨批;非注释面,S11 注释面口径与 A4「注释面」口径天然不含,不入豁免单——清单见 §2 N3 节末)。 + +### N1 · 完美排雷(21 处 / 9 文件) | 落点 | 行 | 面 | |---|---|---| @@ -83,24 +94,30 @@ | `presentation/views/board_fx_view.gd` | 2、90 | 注释 | | `presentation/views/board_fx_view.gd` | **102** | **对外文案**(`_show_banner("完美排雷 ×2")`) | | `presentation/views/settlement_fx_view.gd` | 14 | 注释 | -| `game/README.md` | 146 | 文档正文 | -| `smoke/smoke_all.gd` | 3512、3516、4076 | 注释/断言描述 | +| `game/README.md` | 146、168、267 | 文档正文(168=v1 遗留观测项清单、267=全屏 States 与模态段,均活文本;v1.3 补 168/267——旧信号过滤因行内别处含「作废/历史」误伤) | +| `smoke/smoke_all.gd` | 3503、3512、3513、3516、4076 | 注释/断言描述(v1.3 补 3503/3513——旧信号过滤因行内「→」误伤) | | `smoke/smoke_all.gd` | **6201** | **冒烟夹具期望字面量**(断言比对用,非注释) | | `tests/smoke/critical-paths.md` | 20 | 文档正文 | -### N2 · 板级(26 处 / 13 文件) +### N2 · 板级(33 处 / 15 文件) -`core/battle_orchestrator.gd`(67、265、470、482、506、507、928、1213)· `core/board_data.gd`(17、53)· `core/treasure_items.gd`(2、41)· `core/minesweeper_rules.gd`(126)· `data/schemas/variation_table.gd`(20、79)· `presentation/main.gd`(914)· `presentation/treasure_interact_controller.gd`(101)· `presentation/views/board_view.gd`(149、511)· `presentation/views/board_cell_unit.gd`(97)· `presentation/views/hero_info_panel_view.gd`(122、162)· `presentation/views/settlement_fx_view.gd`(146)· `smoke/smoke_all.gd`(2588、2630)· `tests/unit/core/feat_vouchers_test.gd`(174) +`core/battle_orchestrator.gd`(67、265、445、470、482、506、507、928、1213)· `core/board_data.gd`(17、53)· `core/treasure_items.gd`(2、41、63)· `core/minesweeper_rules.gd`(126)· `data/schemas/variation_table.gd`(20、79)· `presentation/main.gd`(914)· `presentation/hud_presenter.gd`(40、105)· `presentation/treasure_interact_controller.gd`(101)· `presentation/views/board_view.gd`(149、511、544)· `presentation/views/board_cell_unit.gd`(97)· `presentation/views/hero_info_panel_view.gd`(122、162)· `presentation/views/settlement_fx_view.gd`(146)· `smoke/smoke_all.gd`(1846、2588、2630)· `smoke/ui_input_probe.gd`(4)· `tests/unit/core/feat_vouchers_test.gd`(174) -### N3 · 门票(38 处 / 11 文件;其中 3 处移交,本批做 35 处) +(v1.3 补 7 处 2 文件:`hud_presenter.gd` 全文件、`ui_input_probe.gd` 全文件不在 v1.2 清单内;`battle_orchestrator.gd:445`/`treasure_items.gd:63`/`board_view.gd:544`/`smoke_all.gd:1846` 因行内含「→/禁用/登记」子串被旧信号过滤误伤——全是活注释。) -`core/adventure_runner.gd`(67、68、69、477、664、751、771、788、796、1033、1034)· `core/level_runner.gd`(51、781、826、831)· `data/schemas/adventure_table.gd`(92、96、97)· `data/schemas/shop_table.gd`(18)· `data/tables/shop.tres`(104)· `presentation/curio_interact_controller.gd`(89、217、237)· `presentation/views/curio_pick_overlay.gd`(110)· `smoke/level_autoplay.gd`(226)· `smoke/smoke_all.gd`(1362、1363、1370、1378、1379、1382、1384、5306)· `tests/unit/core/pool_case_d_test.gd`(98)· `tests/unit/presentation/reward_overlay_test.gd`(41) +### N3 · 门票(39 处 / 12 文件;其中 3 处移交,本批做 36 处) + +`core/adventure_runner.gd`(67、68、69、477、664、751、771、788、796、1033、1034)· `core/level_runner.gd`(51、781、826、831)· `core/config_db_cross_validator.gd`(103)· `data/schemas/adventure_table.gd`(92、96、97)· `data/schemas/shop_table.gd`(18)· `data/tables/shop.tres`(104)· `presentation/curio_interact_controller.gd`(89、217、237)· `presentation/views/curio_pick_overlay.gd`(110)· `smoke/level_autoplay.gd`(226)· `smoke/smoke_all.gd`(1362、1363、1370、1378、1379、1382、1384、5306)· `tests/unit/core/pool_case_d_test.gd`(98)· `tests/unit/presentation/reward_overlay_test.gd`(41) + +(v1.3 补 `config_db_cross_validator.gd:103`——「T5 门票豁免」活注释,旧信号过滤因行内「豁免」子串误伤;`level_runner.gd:832` 入豁免单,见上口径表。) **移交 3 处**(不属本批,去向=文档轨批):`data/tables/shop.tres:86` display_name「奇物门票」、`presentation/curio_interact_controller.gd:165`/`:166` 玩家可见文案「奇物门票/开一次奇物三选一」。 -### N4 · 正主(12 处 / 9 文件,含误报 1 处) +### N4 · 正主(14 处 / 10 文件,含误报 1 处) -`core/adventure_runner.gd:59` · `core/treasure_items.gd:57` · `presentation/views/board_cell_unit.gd:111`/`112` · `presentation/views/board_view.gd:122` · `smoke/board_shot_probe.gd:31` · `smoke/layout_probe.gd:2` · `smoke/shot_probe.gd:3`/`28` · `smoke/t17_defer_probe.gd:6`/`20` · `tests/unit/battle_settlement/damage_math_test.gd:36`(**误报**——「正主角池」是「正主」+「角池」,非词面命中,不改) +`core/adventure_runner.gd:59` · `core/treasure_items.gd:57` · `presentation/views/board_cell_unit.gd:111`/`112` · `presentation/views/board_view.gd:122`/`843` · `smoke/board_shot_probe.gd:31` · `smoke/layout_probe.gd:2` · `smoke/shot_probe.gd:3`/`28` · `smoke/t17_defer_probe.gd:6`/`20` · `tests/static_scan.sh:73` · `tests/unit/battle_settlement/damage_math_test.gd:36`(**误报**——「正主角池」是「正主」+「角池」,非词面命中,不改) + +(v1.3 补 2 处:`board_view.gd:843`「正主 :163 照抄」(活注释,旧信号过滤因「→」误伤)、`static_scan.sh:73`「数值单一事实源的正主」(S3 规则头注,活注释;建议随批改为「数值单一事实源自身」一类等价措辞——代拍板 1)。`adventure_runner.gd:403` 入豁免单,见上口径表。) ### N5 · 落籍(10 处 / 4 文件,含历史注记 1 处) @@ -126,7 +143,7 @@ ### 已核实清零(迭代 31 成果,本批不重复动) -`金币`/`插旗`/`标旗`/`雷格`/`惩罚格`/`旗` 在 `game/` 内疑似现行计数**均为 0**。残留 3 处「旗」全在闸门逻辑(`smoke/smoke_all.gd:1319` 禁字面检查)与字形检查夹具(`tests/unit/presentation/ui_font_asset_test.gd:18`/`:19`),属对照性文本。 +`金币`/`插旗`/`标旗`/`雷格`/`惩罚格`/`工作日志` 在 `game/` 内现行计数**均为 0**(v1.3 复核确认)。残留 6 处「旗」=闸门自指 5 处(`smoke/smoke_all.gd:1319`/`:1321`、`tests/unit/presentation/ui_font_asset_test.gd:18`/`:19`、`data/tables/feats.tres:10`)+更名记载 1 处(`feats.tres:11`「旗〔旧称〕=封印」)——前者由契约 9 自指豁免覆盖,后者属 B2 对照性文本;单字「旗」不入 S11 词表(契约 7 排除单)。另「巢穴」20 处全为玩家可见专名「巢穴预告」与风味层表述(`treasure_items.tres:99`/`main.gd:913` 等),同入排除单;「排雷」64 处 / 26 个文件(「排雷玩法/排雷规则」内部机制名)不扩大禁词面(§10 已裁)。 **复现命令**(仓库根):`grep -rn "完美排雷\|板级\|门票\|正主\|落籍" game/ --include=*.gd --include=*.tres --include=*.md --include=*.json --include=*.sh` @@ -140,11 +157,15 @@ 4. 🔴 **完美封印判据单点**——「是否已破」只允许由 `battle_orchestrator.perfect_sweep_earned()` 的有效误标口径派生,禁在 `grant_segment.gd` 另立 RAW 计数判据;两处口径不一致即为缺陷。 5. 🔴 **游戏行为零变化**(N1–N5、N7 判据修正前)——纯中文文本替换,禁止改动逻辑、数值、权重、条件判断。N7 判据修正是**本批唯一允许的逻辑改动**,其验收为「日志文案与真值一致」,不改奖励兑付结果。 6. 🔴 **S11 规则先落、后修码**——先把规则写进 `game/tests/static_scan.sh` 并跑出红,再动注释(code-conventions 缺陷-规范对照表纪律)。 -7. 🔴 **S11 词表范围=本批清理范围,且从术语表解析不内联**——词表面=`design/gdd/术语表.md`「退役词对照」节第一列全部词面(去括号注),**显式追加 `完美排雷` 完整短语**(该词受「对外命名纪律」约束,不在退役词对照表里,故需显式列入)。**明确不收**:①术语表「用语规范」A 表词面(`不得`/`报错`/`对标`/`若干`/`buff`)——§4 已列「不做」,收进来批末必然红;②单字「雷」——会误伤 26 处保留词「排雷玩法/排雷规则」(内部机制名,§10 明定不扩大禁词面)。**禁止在脚本里另抄一份词表**(单一事实源红线,ADR 漂移教训同类)。A 表词将来若被裁决纳入,另行扩词表并单独立批清扫。 +7. 🔴 **S11 词表=术语表解析+显式排除单,不内联第二份**——词表面从 `design/gdd/术语表.md`「退役词对照」节解析第一列全部词面(去括号注)得 12 个,**显式追加 `完美排雷` 完整短语**(受「对外命名纪律」约束,不在退役词对照表里),再套**显式排除单 2 个**(带理由;排除单是词表的元数据不是第二份词表): + - **排除 `巢穴`**:`game/` 内 20 处命中全为玩家可见专名「巢穴预告」(`treasure_items.tres:99` display_name/`main.gd:913` toast 等)与风味层表述(「惊动巢穴」「巢穴敌」)——术语表该行自带「世界观风味层除外」注,B3 专名豁免;「巢穴(机制表述)」的清理**不在本批范围**(§4 不做),收进来批末 S11 必红 20 处。巢穴机制表述换代需用户裁后另立批。 + - **排除 `旗`**:`tools/doc_term_audit.py` 既有判例「旗单字不入表(词面误报率高——旗帜/红旗等同族误伤)」;`game/` 内 6 处命中=5 处闸门自指(契约 9 覆盖)+1 处更名记载(`feats.tres:11`,B2 对照性文本)。单字旗如需清理随旗概念批另裁。 + **明确不收**:①术语表「用语规范」A 表词面(`不得`/`报错`/`对标`/`若干`/`buff` 等)——§4 已列「不做」,收进来批末必然红;②单字「雷」——会误伤 64 处 / 26 个文件的保留词「排雷玩法/排雷规则」(内部机制名,§10 明定不扩大禁词面)。**禁止在脚本里另抄一份词表**(单一事实源红线,ADR 漂移教训同类)。A 表词/巢穴/旗将来若被裁决纳入,另行扩词表并单独立批清扫。 8. 🔴 **S11 必须带两道零命中自检**——①扫描面文件数为零即判红;②从术语表解析出的词面数为零即判红(沿 S3 教训:路径写歪或表格结构变了时,自检一起歪、一起红,不会静默恒绿)。 -9. 🔴 **S11 闸门自指豁免**——命中行若属「检查禁用词本身」的闸门形态(行内含 `contains(`/`find(`/`grep`/`has_char(`/`禁「`/`禁『`/`零「`/`零『` 等检查或禁令表述),或含 `doc_term_audit.py` 同源的对照/历史信号,一律豁免、不判红。现存受此豁免的两处:`game/smoke/smoke_all.gd:1319`(禁字面检查逻辑)与 `game/tests/unit/presentation/ui_font_asset_test.gd:18`/`:19`(字形覆盖夹具)。 -9. 🔴 **禁碰并行会话在改的文件**——`AGENTS.md` 与 `design/dev/code-conventions.md`(分支 `changelog-retire-20261019` 在盘未合回)。S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`。 -10. 🔴 **对照性文本豁免**——含退役/更名/禁令等信号的行不改写(术语表用语规范 B 类豁免条款)。 +9. 🔴 **S11 闸门自指豁免**——命中行若属「检查禁用词本身」的闸门形态(行内含 `contains(`/`find(`/`grep`/`has_char(`/`禁「`/`禁『`/`零「`/`零『` 等检查或禁令表述),或含 `doc_term_audit.py` 同源的对照/历史信号,一律豁免、不判红。现存受此豁免的 5 处:`game/smoke/smoke_all.gd:1319`(禁字面检查逻辑)/`:1321`(零「雷/旗」断言描述)、`game/tests/unit/presentation/ui_font_asset_test.gd:18`/`:19`(字形覆盖夹具)、`game/data/tables/feats.tres:10`(desc 禁令引举)。**S11 规则说明自身与登记行一律用禁令引举句式**(如「禁「板级」「门票」……」)——既落 B2 对照性文本豁免,又天然触发本条自指豁免(否则闸本体的头注会被自己判红)。 +10. 🔴 **禁碰并行会话在改的文件**——`AGENTS.md` 与 `design/dev/code-conventions.md`(分支 `changelog-retire-20261019` 在盘未合回)。S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`。 +11. 🔴 **对照性文本豁免**——含退役/更名/禁令等信号的行不改写(术语表用语规范 B 类豁免条款);本批的 B 类落点已全部显式枚举进 §2 豁免单,不再用行内子串现场判定。 +12. 🔴 **parity 闸本批不发起、漂移记档、合回后另立重锚批**——N7 的 `_emit_row` 后移+`hl` 两态化会互换 `seal_miss`/`insurance_used` 两行的日志顺序并改写豁免态 `highlight`(`playtest_logger._on_step_row` 逐行落盘、七公共字段含 `highlight`),而 11 号闸对 JSONL 按 sha256 逐位比对——批准实跑必红,且闸令明载「不得借机重锚」。故本批 **不发起 parity**(回执落 NEED-APPROVAL:该态指纹记 skip、入 not_run,`all_green` 不受影响);预期漂移(豁免态/未豁免态各一例)写进实现报告「已记档差异」节;合回后另立**用户批准**的 parity 重锚批并登记 06,不得借任何批「顺手」重锚。N7 的行为正确性验收走 A10/A11/A12 正向断言(测试三层分工纪律①主力)。 --- @@ -152,13 +173,13 @@ **做**: -1. `game/` 内 `完美排雷`→`完美封印`(16 处,含对外文案 3 处) -2. `game/` 内注释面 `板级`→`整图`(26 处) -3. `game/` 内注释面 `门票`→`专长凭证`(35 处,剔除移交 3 处) -4. `game/` 内注释面 `正主`→`现行事实源`(11 处,剔除误报 1 处) -5. `game/` 内注释面 `落籍`→`已入库`(9 处,剔除历史注记 1 处) +1. `game/` 内 `完美排雷`→`完美封印`(21 处,含对外文案 3 处) +2. `game/` 内注释面 `板级`→`整图`(33 处) +3. `game/` 内注释面 `门票`→`专长凭证`(36 处,剔除移交 3 处与豁免 1 处) +4. `game/` 内注释面 `正主`→`现行事实源`(13 处,剔除误报 1 处与豁免 1 处) +5. `game/` 内注释面 `落籍`→`已入库`(9 处,剔除豁免 1 处) 6. **N7**:封印未中行归因锚改用有效误标判据,文案按两态改写 -7. 代码域静态扫描闸新增 S11 规则(词表=退役词对照+`完美排雷`;含两道零命中自检与闸门自指豁免) +7. 代码域静态扫描闸新增 S11 规则(词表=术语表解析+显式排除单〔巢穴/旗〕+`完美排雷`;含两道零命中自检、闸门自指豁免与 4 处显式留档豁免) 8. `game/README.md`/`game/tests/README.md` 同步 9. 全量冒烟+单元+探针验证,绿数与基线一致 @@ -171,6 +192,7 @@ | `shop.tres:86`「奇物门票」与 `curio_interact_controller.gd:165-166` 玩家文案 | 属 奇物/专长 归类表述,与 06「冒记案遗留待裁两项」第①项同源 → 交文档侧定性后另走传导批 | | `AGENTS.md`/`design/dev/code-conventions.md` | 并行会话 `changelog-retire-20261019` 在盘未合回,本批禁碰 | | 术语表 A 表词(不得 14/报错 18/对标 1/若干 1/buff 22) | 待用户另裁;裁入则新立 06 条目与卡片 | +| 「巢穴(机制表述)」换代与单字「旗」清理 | S11 显式排除单已收理由(巢穴=玩家专名 B3+风味层除外注;旗=doc_term_audit 既有判例+6 处全豁免);两项清理均需用户裁后另立批(06 登记) | | doc-conventions 第 4 节流程动词(收口 128/随批 20/台账 17/对拍 16/在飞 10/落文 2) | 同上 | | 简明技术中文(STC)通用禁用词(缺省 105/情况 26/入参·出参 23/比较·较为·相对 22 等) | 同上 | | 任何游戏逻辑/数值改动(N7 判据修正除外) | 禁止 | @@ -208,7 +230,7 @@ | `game/README.md` | 切片架构说明 | 措辞换代 | | `game/core/battle_orchestrator.gd` | 战斗编排器 | 注释+对外文案换代 | | `game/core/settlement/grant_segment.gd` | 授予段 | 注释换代 + **N7 判据修正** | -| `game/core/minesweeper_rules.gd` 等 11 个 .gd | 注释承载 | 注释换代 | +| `game/core/minesweeper_rules.gd` 等 36 个 .gd | 注释承载 | 注释换代 | | `game/data/tables/*.tres` | 数据表注释 | 注释换代 | | `game/smoke/smoke_all.gd` | 冒烟断言 | 注释、断言描述与夹具期望字面量换代 | | `game/tests/unit/**` | 单元测试 | 注释与断言描述换代 | @@ -226,17 +248,18 @@ ### T1 · S11 规则落闸并见红(≈1.0–1.5h) -- [ ] 在 `game/tests/static_scan.sh` 头部注释补 S11 一行说明(规则名+权威出处+扫描面+词表来源) -- [ ] 新增 S11 段:扫描面=`game/` 全域(.gd/.tres/.md/.json),与迭代 31 V4 判据同口径 -- [ ] 逐行取注释文本段(`#`/`;` 前缀),剔除含对照/历史信号的行 -- [ ] 词表面从 `design/gdd/术语表.md`「退役词对照」节解析第一列全部词面(去括号注),**显式追加 `完美排雷` 完整短语**;不收 A 表词、不收单字「雷」(契约 7) -- [ ] 命中行先过闸门自指豁免(行内含 `contains(`/`find(`/`grep`/`has_char(`/`禁「`/`禁『`/`零「`/`零『` 即跳过),再判红(契约 9) +- [ ] 在 `game/tests/static_scan.sh` 头部注释补 S11 说明(规则名+权威出处+扫描面+词表来源+豁免条款;**一律用禁令引举句式**,契约 9 末款) +- [ ] 新增 S11 段:扫描面=`game/` 全域 `.gd`/`.tres`/`.md`/`.json`/`.sh`(迭代 31 V4 四类+`.sh`——闸脚本自身注释面;`.txt` 不收=第三方字体许可证非本仓库文本) +- [ ] 注释文本段按类型取:`.gd`/`.sh` 取 `#` 后文本(整行注释与行尾注释都取);`.tres` 取 `;` 后文本;`.md` 取整行(文档正文即注释面);`.json` 无注释语法——保留扩展名但不产生注释段(V4 先例,`game/` 下 .json 五词现行零命中) +- [ ] 词表面从 `design/gdd/术语表.md`「退役词对照」节解析第一列全部词面(去括号注)得 12 个,**显式追加 `完美排雷`**,套显式排除单 `巢穴`/`旗`(契约 7,理由写在头注);不收 A 表词、不收单字「雷」 +- [ ] 三层豁免依序过:①闸门自指(行内含 `contains(`/`find(`/`grep`/`has_char(`/`禁「`/`禁『`/`零「`/`零『` 即跳过,契约 9);②显式留档豁免单 4 处(§2 口径表:`enemy.tres:653`/`level_runner.gd:832`/`adventure_runner.gd:403`/`damage_math_test.gd:36`);③非注释面行不取(数据值与字符串字面量天然不入段——移交 3 处由此天然不含) - [ ] 自检一:扫描面文件数为零即 `echo "[static_scan] S11 FAIL: 扫描面为空"` 并 `fail=1` -- [ ] 自检二:解析出的词面数为零即 `echo "[static_scan] S11 FAIL: 词表解析为空"` 并 `fail=1` +- [ ] 自检二:解析并套排除单后的词面数为零即 `echo "[static_scan] S11 FAIL: 词表解析为空"` 并 `fail=1` - [ ] 命中即打印 `file:line + 命中词`,段末 `fail=1` -- [ ] 在 `game/tests/README.md` 的静态扫描登记处补 S11 一行(规则名/扫描面/词表来源/豁免条款) +- [ ] 在 `game/tests/README.md` 的静态扫描登记处补 S11 一行(规则名/扫描面/词表来源/三层豁免条款;同用禁令引举句式) - [ ] 注入验证:在 `game/core/battle_orchestrator.gd` 某注释里临时写回「板级」一词 → 跑 `bash game/tests/static_scan.sh` 见红并记输出摘要 → `git checkout -- game/core/battle_orchestrator.gd` 精确还原 → 记录进实现报告变异验证表 - [ ] 反向验证:在 `game/smoke/smoke_all.gd:1319`(禁字面检查行)写回原句 → 跑闸**仍为绿**(验证自指豁免生效)→ 还原 +- [ ] 反向验证二:把排除单里的 `巢穴` 删掉 → 跑闸见红且命中行含 `treasure_items.tres:99`(验证排除单是唯一拦住巢穴的机制)→ 还原 **取用**:无。 **产出**:`game/tests/static_scan.sh` 的 `S11` 段(退出码语义=任一硬失败规则命中即 `exit 1`,与现役同段同规)。 @@ -248,17 +271,18 @@ - [ ] `game/core/battle_orchestrator.gd:925` 行内字符串 `"完美排雷!清图奖励 ×2"` → `"完美封印!清图奖励 ×2"` - [ ] `game/presentation/views/board_fx_view.gd:102` `_show_banner("完美排雷 ×2")` → `_show_banner("完美封印 ×2")` - [ ] `game/presentation/views/battle_log_view.gd:194` 按两态改写(见 T7,判据修正后语义才成立;此处只落文本占位,不留「已破」字样在豁免态) -- [ ] 其余 13 处(11 处代码注释/文档注释 + smoke_all.gd:3512/3516/4076 断言描述 + :6201 夹具期望字面量)逐处换代(清单见 §2 N1 表) +- [ ] 其余 18 处(8 处代码注释/文档注释:`battle_orchestrator.gd:265`/`:911`/`:1296`、`settlement_table.gd:8`、`row_pacer.gd:92`、`board_fx_view.gd:2`/`:90`、`settlement_fx_view.gd:14`;4 处文档正文:`game/README.md:146`/`:168`/`:267`、`tests/smoke/critical-paths.md:20`;5 处 smoke 注释/断言描述:`smoke_all.gd:3503`/`:3512`/`:3513`/`:3516`/`:4076`;1 处夹具期望字面量:`smoke_all.gd:6201`)逐处换代(清单见 §2 N1 表) - [ ] 跑 §2 末复现命令确认 `完美排雷` 零命中 **取用**:无。 **产出**:`game/` 内「完美排雷」零命中;对外文案三处读作「完美封印」。 -### T3 · 板级 → 整图(≈1.0h) +### T3 · 板级 → 整图(≈1.5h) -- [ ] `game/core/battle_orchestrator.gd` 8 处(67/265/470/482/506/507/928/1213)换代 +- [ ] `game/core/battle_orchestrator.gd` 9 处(67/265/445/470/482/506/507/928/1213)换代 - [ ] `game/core/board_data.gd` 2 处(17/53)换代 -- [ ] 余 11 文件 16 处逐处换代(清单见 §2 N2) +- [ ] `game/presentation/hud_presenter.gd` 2 处(40/105)+ `game/smoke/ui_input_probe.gd` 1 处(4)换代(v1.3 补——两文件整文件不在旧清单内) +- [ ] 余 11 文件 19 处逐处换代(清单见 §2 N2:treasure_items 2/41/63、minesweeper_rules 126、variation_table 20/79、main 914、treasure_interact_controller 101、board_view 149/511/544、board_cell_unit 97、hero_info_panel_view 122/162、settlement_fx_view 146、smoke_all 1846/2588/2630、feat_vouchers_test 174) - [ ] 跑 §2 末复现命令确认 `板级` 零命中 **取用**:无。 @@ -267,7 +291,8 @@ ### T4 · 门票 → 专长凭证(注释面,≈1.0h) - [ ] `game/core/adventure_runner.gd` 11 处注释换代(67/68/69/477/664/751/771/788/796/1033/1034) -- [ ] `game/core/level_runner.gd` 4 处(51/781/826/831) +- [ ] `game/core/level_runner.gd` 4 处(51/781/826/831)换代(`:832` 为历史注记,豁免单内不动) +- [ ] `game/core/config_db_cross_validator.gd:103` 注释换代(v1.3 补——「T5 门票豁免」活注释;`level_runner.gd:832` 同场豁免见 §2 口径表) - [ ] `game/data/schemas/adventure_table.gd` 3 处(92/96/97)+ `shop_table.gd:18` - [ ] `game/data/tables/shop.tres:104` 注释换代 - [ ] `game/presentation/curio_interact_controller.gd` 3 处(89/217/237)+ `curio_pick_overlay.gd:110` @@ -275,21 +300,21 @@ - [ ] 复核标识符与数据键零改动(`feat_ticket` 族、`"feat_ticket"` 行族键、存档键) **取用**:无。 -**产出**:`game/` 注释面「门票」零命中;标识符与数据键保持原样。 +**产出**:`game/` 注释面「门票」残留=豁免单 1 处(`level_runner.gd:832`);标识符与数据键保持原样。 ### T5 · 正主 → 现行事实源(≈0.5h) -- [ ] 11 处换代(清单见 §2 N4,剔除 `damage_math_test.gd:36` 误报) +- [ ] 13 处换代(清单见 §2 N4,剔除 `damage_math_test.gd:36` 误报与 `adventure_runner.gd:403` 历史注记;含 v1.3 补的 `board_view.gd:843` 与 `static_scan.sh:73`——后者建议改「数值单一事实源自身」一类等价措辞,代拍板 1) **取用**:无。 -**产出**:`game/` 内「正主」零命中。 +**产出**:`game/` 内「正主」残留=豁免单 2 处(`adventure_runner.gd:403` 历史注记+`damage_math_test.gd:36` 误报)。 ### T6 · 落籍 → 已入库(≈0.5h) - [ ] 9 处换代(清单见 §2 N5,剔除 `enemy.tres:653` 历史注记) **取用**:无。 -**产出**:`game/` 内「落籍」零命中。 +**产出**:`game/` 内「落籍」残留=豁免单 1 处(`enemy.tres:653` 历史注记)。 ### T7 · N7 归因锚判据修正(≈1.5h) @@ -298,6 +323,7 @@ - [ ] 把 `core/settlement/grant_segment.gd:302` 的 `oc._emit_row("seal_miss", ...)` **后移**到 `for h in oc._fx_emit("seal_missed", ...)` 循环(:308-317)**之后**——循环结束后 `_perfect_forgiven` 已就位,判据才有真值可用 - [ ] 判据改有效误标:`var hl := "perfect_broken" if oc._perfect_hit_false - oc._perfect_forgiven == 1 else ""`(替代原 :300 的 RAW 计数 `oc._perfect_hit_false == 1`) - [ ] 确认行序调换的零影响:`grep -n "insurance_used\|perfect_insurance" game/smoke/smoke_all.gd` 已实测**零命中**——冒烟未断言这两行的相对顺序,调换不涉断言 +- [ ] **parity 漂移记档(契约 12)**:`playtest_logger._on_step_row` 逐行落盘且含 `highlight` 字段——本修改互换 `seal_miss`/`insurance_used` 两行顺序并改写豁免态 `hl`,11 号闸 JSONL 逐位比对必红;本批不发起 parity,把预期漂移(豁免态/未豁免态各一例,含两行顺序与 `highlight` 取值)写进实现报告「已记档差异」节,供合回后的用户批准重锚批对照 - [ ] 文案两态:未豁免(`hl == "perfect_broken"`)→ `(本图完美封印已破——清图奖励不再加倍)`;已豁免(`hl == ""`)→ `(首次封印落空已豁免——不计入完美封印判定)` - [ ] 豁免态**不加金框**——`hl == ""` 时 `battle_log_view.gd:195` 走普通色分支;金框语义=强调负面事件,豁免是正向事件,靠同批已存在的 `insurance_used` 行(:316-317)承载反馈即可。不新增高光标记 - [ ] 正向断言 A10/A11(见 §7) @@ -309,14 +335,14 @@ - [ ] 跑代码域档验收(按本批改动域选档),确认所选域全绿 - [ ] 确认回执 `game/tests/.gates/receipt.json` 的 commit = 分支 tip 且 `all_green=true` -- [ ] 写 `reports/iter32-实现报告-<日期>.md`(各卡状态+改前改后读数对照+实机目检总清单+遗留读数义务) +- [ ] 写 `reports/iter32-实现报告-<日期>.md`(各卡状态+改前改后读数对照+实机目检总清单+遗留读数义务+**已记档差异节**:parity 预期漂移两例〔豁免态/未豁免态各一:`seal_miss`/`insurance_used` 两行顺序互换+豁免态 `highlight` 取值〕+**06 登记项**:合回后用户批准的 parity 重锚批) - [ ] 写 `reports/iter32-代拍板-<日期>.md` - [ ] 写 `reports/iter32-反哺点-<日期>.md`(§5 每条都要有落点) **取用**:T1–T7 全部产出。 **产出**:`reports/` 三份产出物 + 可合回的分支 tip。 -**估时合计 ≈8.5–10.0h**。切分预案(超 8h 即生效):T3/T4 各拆「核心层」与「呈现+测试」两卡串行施工;T7 独立成卡可单独验收,必要时可拆出本批另立缺陷批。 +**估时合计 ≈9.0–10.5h**(v1.3:T3 26→33 处、T2 补 4 处、T4/T5 各补 1–2 处、T1 增反向验证二,T3 估时 1.0→1.5h)。切分预案(超 8h 即生效):T3/T4 各拆「核心层」与「呈现+测试」两卡串行施工;T7 独立成卡可单独验收,必要时可拆出本批另立缺陷批。 --- @@ -326,12 +352,12 @@ | # | 需求点 | 测什么(断言/行为) | 怎么测(落点) | 谁验 | |---|---|---|---|---| -| A1 | N1 | `game/` 内 `完美排雷` 疑似现行计数 == 0 | grep 复现命令+同脚本口径 | 自动(S11+收尾 grep) | -| A2 | N1 | 对外文案三处文本恰为「完美封印…」,且不含「雷」字面 | 新冒烟断言:取清图高光行 `display_name`,断言 `find("雷") == -1` 且 `find("完美封印") >= 0`;落点 `game/smoke/smoke_all.gd` 清图段 | -| A3 | N2 | `game/` 内 `板级` 计数 == 0 | 同 A1 | 自动 | -| A4 | N3 | `game/` 注释面 `门票` 计数 == 0;且 `feat_ticket` 标识符与存档键**保持原样** | 同 A1 + 断言:`_feat_ticket_pity` 等标识符仍在位 | 自动 | -| A5 | N4 | `game/` 内 `正主` 计数 == 0 | 同 A1 | 自动 | -| A6 | N5 | `game/` 内 `落籍` 计数 == 0(历史注记行豁免) | 同 A1 | 自动 | +| A1 | N1 | `game/` 内 `完美排雷` 计数 == 0(全清,无豁免) | grep 复现命令+同脚本口径 | 自动(S11+收尾 grep) | +| A2 | N1 | 对外文案三处文本恰为「完美封印…」,且不含「雷」字面 | 新冒烟断言:取清图高光行 `display_name`,断言 `find("雷") == -1` 且 `find("完美封印") >= 0`;落点 `game/smoke/smoke_all.gd` 清图段。另两处字符串字面量(`board_fx_view.gd:102` banner/`battle_log_view.gd:194` 行)S11 扫不到(只扫注释面)——同段加静态读取断言:读两处源文本行,`find("雷") == -1` 且含「完美封印」 | 自动 | +| A3 | N2 | `game/` 内 `板级` 计数 == 0(全清,无豁免) | 同 A1 | 自动 | +| A4 | N3 | `game/` 注释面 `门票` 计数 == 豁免单 1 处(`level_runner.gd:832` 历史注记);且 `feat_ticket` 标识符与存档键**保持原样** | 同 A1(注释面口径天然不含移交 3 处)+ 断言:`_feat_ticket_pity` 等标识符仍在位 | 自动 | +| A5 | N4 | `game/` 内 `正主` 计数 == 豁免单 2 处(`adventure_runner.gd:403` 历史注记+`damage_math_test.gd:36` 误报) | 同 A1 | 自动 | +| A6 | N5 | `game/` 内 `落籍` 计数 == 豁免单 1 处(`enemy.tres:653` 历史注记) | 同 A1 | 自动 | | A7 | N6 | S11 规则在位:注入禁用词 → 退出码 1 且输出含 `S11 FAIL`/命中行 | 注入实验,落点 `game/tests/static_scan.sh` | 自动(人工执行一次取证) | | A8 | 全域 | 冒烟绿数 == 基线 1151、单元 34 套全绿、探针段绿 | 跑所选域档 | 自动 | | A9 | 全域 | 回执 commit == 分支 tip 且 `all_green=true`,零新增红 | 跑闸后读 `game/tests/.gates/receipt.json` | 自动(合回闸) | @@ -339,9 +365,9 @@ | **A11** | **N7** | **装备完美保险:本战首次标错 → `seal_miss` 行的 `highlight` 字段 == `""`,且 `perfect_sweep_earned() == true`(加倍仍发)** | 同上 | 自动 | | **A12** | **N7** | 两态文案常量与 `battle_log_view.gd` 呈现一致:`_format_row` 对 `hl=="perfect_broken"` 输出「已破」态、对 `hl==""` 输出豁免态,两态均不含「雷」字面 | 断言落点 `tests/unit/core/feat_vouchers_test.gd`(取行字段后按同一分支规则格式化比对) | 自动 | -**测试方式两分法**:A1–A7、A10–A11 属能力验证(静态扫描/断言直取数据)与取证实验;A8–A9 为运行期验证。玩家可见文案的最终观感归**用户目检**(登记不阻塞):结算明细中封印未中行的两态文案可读性。 +**测试方式两分法**:A1–A7、A10–A12 属能力验证(静态扫描/断言直取数据)与取证实验;A8–A9 为运行期验证。玩家可见文案的最终观感归**用户目检**(登记不阻塞):结算明细中封印未中行的两态文案可读性。 -**闸口径**:按本批改动域选档跑 `tools/run_all_gates.sh`(本批只触 `game/` 与 `reports/` → 代码域档);跑完写回执。 +**闸口径**:按本批改动域选档跑 `tools/run_all_gates.sh`(本批只触 `game/` 与 `reports/` → 代码域档);跑完写回执。**11 号 parity 闸将落 NEED-APPROVAL**(diff 触 `game/core/settlement/`)——该态指纹记 skip、入 `not_run`,`all_green` 不受影响(契约 12:本批不发起、漂移记档、合回后另立用户批准的重锚批)。 **回归措辞模板**:「里程碑步(波/T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试/工具先行孤立验证再并入全套」。 @@ -354,7 +380,8 @@ | S11 扫描面 | 临时把 `DIR_CORE` 改成不存在目录 | `bash game/tests/static_scan.sh` | `S11 FAIL: 扫描面为空` | | **N7 判据(反)** | `grant_segment.gd` 判据改回 `_perfect_hit_false == 1`(RAW 计数) | `tests/unit/core/feat_vouchers_test.gd` | 断言 A11 红(装备专长时 `highlight` 应为 `""` 却得 `"perfect_broken"`) | | **N7 判据(正)** | 判据改成 `_perfect_hit_false + _perfect_forgiven == 1`(符号写反) | 同上 | 断言 A10 红(未装备专长时 `highlight` 应为 `"perfect_broken"` 却得 `""`) | -| **S11 自指豁免** | 去掉 S11 的闸门自指豁免分支 | `bash game/tests/static_scan.sh` | `smoke_all.gd:1319` 与 `ui_font_asset_test.gd:18` 判红 | +| **S11 自指豁免** | 去掉 S11 的闸门自指豁免分支 | `bash game/tests/static_scan.sh` | `smoke_all.gd:1319`/`:1321`、`ui_font_asset_test.gd:18`、`feats.tres:10` 判红 | +| **S11 排除单** | 把排除单里的 `巢穴` 删掉 | `bash game/tests/static_scan.sh` | 判红且命中行含 `treasure_items.tres:99`(「巢穴预告」display_name) | 注入后一律 `git checkout -- ` 精确还原,四件(变异点 file:行/跑的闸/红输出摘要/还原结论)记进实现报告变异验证记录表。 @@ -370,7 +397,7 @@ 3. 改前改后同种子读数不一致; 4. S11 注入后不变红(判据无效); 5. 触碰并行会话在改文件(`AGENTS.md`/`design/dev/code-conventions.md`); - 6. **N7 上移 `_perfect_forgiven` 累加后,奖励兑付结果与改前不一致**(说明改到了兑付行为,而非只改文案判据)。 + 6. **N7 后移 `_emit_row` 后,奖励兑付结果与改前不一致**(说明改到了兑付行为,而非只改文案判据)。 --- @@ -398,6 +425,8 @@ | 完美排雷 | 全库统一换代为「完美封印」,含代码内部注释——2026-10-19 用户裁;据此推翻 `需求卡片-凭证件裁削批`:108「内部开发用语按 v3.15 纪律保留」半句,卡片条款订正归文档轨批 | | 排雷(模块名) | **不扩大禁词面**。「排雷玩法/排雷规则」是内部机制名(=扫雷推理层的玩法动作总称,见 `00-游戏概念.md:5`),GDD 目录即 `systems/排雷循环/`,术语表正文在用,26 个文件保持原样 | | 门票 | 仅换代注释措辞;标识符与数据键零改动;玩家可见两处(`shop.tres:86`/`curio_interact_controller.gd:165-166`)移交文档侧定性 | -| 归因锚判据(N7) | 并入本批:`grant_segment.gd:300` 改用有效误标口径(总数 − 豁免数),豁免累加上移到 `_emit_row` 之前;文案按两态改写——2026-10-20 用户裁 | +| 归因锚判据(N7) | 并入本批:`grant_segment.gd` 封印未中行改判有效误标口径(误标总数 − 豁免数),`_emit_row` 后移到 `_fx_emit` 豁免循环之后使判据有真值可用;文案按两态改写——2026-10-20 用户裁(修法 v1.2 定型:上移豁免累加需重复调用 `_fx_emit` 会重复消费限次,已核实不可行) | **禁用词机检闸不扩到 `game/`**(用户裁:代码与文档分开管理);代码侧改用代码域自己的静态扫描闸 S11,词表从 `design/gdd/术语表.md` 解析,不内联第二份。 + +**S11 显式排除单 2 词**(v1.3 工程推导,非用户裁决——依据:术语表该行自带风味层除外注+B3 专名豁免+`doc_term_audit.py` 既有判例):`巢穴`(20 处全为玩家专名「巢穴预告」与风味层表述,机制表述换代需用户裁后另立批)、`旗`(单字误报率高,6 处残留全豁)。A 表词/巢穴机制表述/单字旗将来若被裁决纳入,另行扩词表并单独立批清扫。 From f513463d27e5c85228d57860757e71687d7ce13a Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 06:46:12 +0800 Subject: [PATCH 08/59] =?UTF-8?q?docs(=E6=95=88=E6=9E=9C=E5=BC=95=E6=93=8E?= =?UTF-8?q?=E6=97=A0=E7=8A=B6=E6=80=81=E5=8C=96=C2=B7=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E9=97=AD=E5=90=88):=20=E6=8F=90=E6=A1=88=20v1.2=20=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=94=B9=E3=80=8C=E5=8F=AF=E5=86=99=E5=8D=A1=E3=80=8D?= =?UTF-8?q?=E2=80=94=E2=80=94=C2=A74.3=20=E5=85=AD=E5=8D=A1=E7=82=B9/?= =?UTF-8?q?=C2=A74.4=20=E5=85=AB=E7=BC=BA=E5=8F=A3/=C2=A74.5=20=E5=85=AD?= =?UTF-8?q?=E6=BE=84=E6=B8=85=E5=85=A8=E9=97=AD=E5=90=88=EF=BC=8C=E5=AE=9A?= =?UTF-8?q?=E5=80=BC=E9=9B=86=E4=B8=AD=20=C2=A77.10=EF=BC=88ctx=3DEffectCo?= =?UTF-8?q?ntext=20=E5=BC=95=E7=94=A8=E6=9D=9F=E6=AF=8F=E6=88=98=E4=B8=80?= =?UTF-8?q?=E6=AC=A1=EF=BC=8F=E5=86=99=E5=8F=A3=E6=94=B9=E9=9D=99=E6=80=81?= =?UTF-8?q?=E7=BA=AF=E5=87=BD=E6=95=B0=20bucket=5Fof=20=E5=8D=95=E7=82=B9?= =?UTF-8?q?=EF=BC=8F=E5=89=8D=E7=BC=80=E6=A0=A1=E9=AA=8C=E5=8F=8C=E8=90=BD?= =?UTF-8?q?=E7=82=B9=EF=BC=8BE2=20=E5=B9=B6=E5=85=A5=20F1=20=E5=B8=A6?= =?UTF-8?q?=E5=BC=95=E5=8F=B7=E6=97=A7=20id=20=E9=9B=B6=E5=91=BD=E4=B8=AD?= =?UTF-8?q?=EF=BC=8FU2=20=E9=9A=8F=E5=AF=BC=E5=87=BA=E6=B6=88=E5=A4=B1?= =?UTF-8?q?=E8=80=8C=E6=B6=88=E8=A7=A3=EF=BC=8Fround=5Fstart=20=E5=AE=9A?= =?UTF-8?q?=E4=BD=8D=20:97=EF=BC=8FG1=20=E5=88=86=E7=BB=84=E5=88=A4?= =?UTF-8?q?=E8=AF=BB=20pain=5Flayers=20=E9=9B=B6=E4=BD=8D=E7=A7=BB?= =?UTF-8?q?=EF=BC=8FB6=20dig=5Fcombo=20=E6=AD=BB=E8=B7=AF=E5=88=A0?= =?UTF-8?q?=E9=99=A4=EF=BC=89=EF=BC=9B06=20=E8=AE=A1=E6=95=B0=E5=99=A8?= =?UTF-8?q?=E6=9D=A1=E7=9B=AE=E6=94=B9=E5=86=99=E6=8E=A8=E8=BF=9B=E5=BE=85?= =?UTF-8?q?=E5=86=99=E5=8D=A1=EF=BC=8B=E6=96=B0=E5=A2=9E=E6=97=A0=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=8E=9F=E5=88=99=E7=BC=BA=E6=9D=A1=E7=9B=AE=E7=99=BB?= =?UTF-8?q?=E8=AE=B0=EF=BC=88--docs=20=E9=97=B8=E5=85=A8=E7=BB=BF=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/gdd/06-待办清单.md | 16 +- .../提案-效果引擎无状态化-2026-10-19.md | 246 +++++++++++++----- 2 files changed, 188 insertions(+), 74 deletions(-) diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index de5f2bc8..bbf26225 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -632,11 +632,11 @@ #### 计数器寿命域未统一(2026-10-18 登记,来源=会话提及,设计面=文档轨) -**现状**:效果的「寿命/作用域」现由三套互不同属的机制拼成,无统一枚举——①`domain` 键仅作用于计数器,只有 `battle`(缺省,每战清零)/`adventure`(跨战持久)两值;②`reset_at: round_start` 表达回合级重置(`feats.tres` 用 4 处);③「按关重置」是**硬编码名单**(`adventure_runner.gd:873-877` 按关清零 `tree_*_used`),不在任何词表内;④**效果自身(非计数器)的寿命没有任何字段**——`effect_engine.gd:32` 的「封印桩本轮/石肤本场」是拿 cap 参数凑的注释,机器不可读。另有名实不符:`domain=adventure` 实际承担「按关重置」语义(代码现状即证:`effect_engine.gd` 词表无寿命字段)。`effect_engine.gd:119-121` 自称「生命周期四态」(跨战持久/按关重置/新冒险清零/断点保留),却未按枚举落地。**后果**:任何带寿命权重的核算(期望收益/强度摊销/「每 X 一次」折算)无法在数据层进行,须逐条读注释或读清除侧代码。**用户已裁:本批不动寿命域**,完美保险按现役 `domain=battle` 落地,此项仅登记、不入本批改动面。 +**现状**:2026-10-19 用户裁定推翻「寿命域统一口径」方向(原方案五档/四档枚举、`domain` 键扩词表整体作废——作废因由=该方案隐含前提「引擎持有状态、需要字段说明它活多久」被推翻,见提案 §8),改走**效果引擎无状态化重构**:引擎零运行时状态,计数器按 round/battle/level/adventure 四桶外置、由各生命周期宿主对象持有(寿命由宿主生灭决定,不再需要寿命字段),归属用 counter_id 前缀表达(`round_`/`lvl_`/`adv_`/无前缀=battle,`meta_` 非法)+加载期强校验。设计定值与实现设计缺口已全部闭合(提案=design/research/提案-效果引擎无状态化-2026-10-19.md,§7 定值+§7.10 闭合)。本条目原指认的三套机制并存问题由该重构一并消解:①`domain`/`reset_at` 两字段随重构删除;②「按关重置」硬编码名单(`adventure_runner.gd:838-841`)随 level 桶宿主化消失;③`run_ledger.gd:42` 空容器早退自锁缺陷随搬运链删除自动消解(代价=行为变更:adventure 域计数器变真跨战持久、天赋树锋/守变真每关限 2 次——削弱方向已定性,提案 §7.7/§7.8)。副产定值:`pain_layers` 名实不符归 battle、`dig_combo` 死读数随重构顺带删除(提案 §7.10.14)。 **归属**:architecture.md 与 game/core/effect_engine.gd(待立独立批) -**状态**:待裁决(是否统一寿命域口径) +**状态**:待裁决(是否统一寿命域口径——2026-10-19 已裁:统一口径方案作废,改走无状态化重构)+文档设计已闭合(design/research/提案-效果引擎无状态化-2026-10-19.md v1.2——2026-10-20 §7.10 闭合)+待写卡 --- @@ -681,3 +681,15 @@ **归属**:①`奇物.md` §1.1/§2.2/v2.2 行(已订正写入文档);②`奇物.md` §1.3(:121/:223/:229)与 `02-系统清单.md:49`(待裁) **状态**:已写入(design/gdd/systems/冒险循环/奇物.md v3.19——第①项专长凭证归类订正)+待裁决(第②项资源判据句,心智模型未对齐,不列候选不提前处置) + +--- + +#### 效果引擎「系统无状态」原则缺架构文档条目(2026-10-20 登记,来源=会话提及,设计面=文档轨) + +**现状**:用户 2026-10-19 会话裁定的 ECS 架构依据(系统无状态——效果引擎这类系统零运行时可变状态、数据由宿主对象持有并随宿主生灭、状态按参数传入系统、系统只做判定)是「效果引擎无状态化」重构批的立项判据(上游条目=本清单「计数器寿命域未统一」,提案=design/research/提案-效果引擎无状态化-2026-10-19.md §7.9 #1),但 `design/engineering/architecture/architecture.md`「架构原则」节(现行 7 条)无「系统无状态」条目——立项判据暂无权威文档出处(2026-10-19 全仓检索「无状态/纯计算」零命中,提案 §10.3 实查;原 `design/registry/` 两 yaml 已随 2026-10-19 用户裁注销删除,无可迁凭据)。重构批是代码批、禁写 `design/`,文档级补条只能另立文档批。 + +**缺口**:一次文档设计讨论——「系统无状态」原则的条文表述(与现行 7 条架构原则的交叉与序位:核心层纯逻辑/fail-fast 两原则与之相邻但不等同)+写入 architecture.md 的批次编排。 + +**归属**:design/engineering/architecture/architecture.md(架构原则节) + +**状态**:待文档设计 diff --git a/design/research/提案-效果引擎无状态化-2026-10-19.md b/design/research/提案-效果引擎无状态化-2026-10-19.md index ecc8ff84..63508a4d 100644 --- a/design/research/提案-效果引擎无状态化-2026-10-19.md +++ b/design/research/提案-效果引擎无状态化-2026-10-19.md @@ -1,9 +1,10 @@ # 提案:效果引擎无状态化(计数器外置·分桶) - **日期**:2026-10-19 +- **版本**:v1.2(2026-10-20 设计闭合版——现行身份标记;改动沿革只查 git commit log) - **性质**:架构重构提案(restructure,非 refactor)——现役设计被判为错误形态,不是打磨 - **上游**:`design/gdd/06-待办清单.md:627`「计数器寿命域未统一」条目(2026-10-18 登记);本提案推翻该条目的解法方向,见 §8 -- **状态**:**草案·设计未闭合**——§7 设计已定值、§7.7 采集定不发起,但 §4.2–§4.5 核验出 3 项阻塞级实现设计缺口(A1 ctx 结构/A2 桶接口/A3 树合成行漏校验)+ 5 项次级缺口 + 6 项需求澄清未对齐,**尚不可写卡** +- **状态**:**设计已闭合·可写卡**——§7 设计定值、§7.7 采集定不发起;§4.3 六项卡点、§4.4 八项实现设计缺口、§4.5 六项需求澄清已于 2026-10-20 复核轮全部闭合(定值与推导依据集中在 §7.10,§3.2/§4.1–§4.5/§5 各节已按定值同步改写);其中 B6(dig_combo 死读数删除)与 §7.9 五条同口径属「约束可推、可否决」项 - **范围**:代码 + 文档,**不含美术** - **关联已定项**:迭代 31 卡①代码术语刷新批 / 卡②凭证件裁削批(完美保险按现役 `domain=battle` 落地)——本提案若先落地,卡②的专长行需同步改形 @@ -77,29 +78,31 @@ ### 3.1 四只桶(宿主决定寿命,不需要寿命字段) -| 桶 | 宿主(候选,见 N1) | 清空方式 | 现役对应 | +| 桶 | 宿主(定值,见 N1) | 清空方式 | 现役对应 | |---|---|---|---| -| `round` | 战斗域对象 | 轮始 `= {}` | `_reset_on_round_start` 名单(4 枚:`round_blast_spent` / `instinct_atk` / `round_mines` / `round_digs`) | +| `round` | `BattleOrchestrator` 公开成员(ctx 构造时挂引用) | 轮始整桶清空(引擎 dispatch 的 round_start 特判泛化——**就地清空**,禁 `= {}` 重赋值断引用) | `_reset_on_round_start` 名单(4 枚:`round_blast_spent` / `instinct_atk` / `round_mines` / `round_digs`) | | `battle` | `BattleOrchestrator`(每战 new) | 随宿主销毁 | `rebuild` 的 `_counters = {}`(8 枚:`geo_types` / `helm_layers` / `skip_pts` / `echo_seals` / `smith_seals` / `fuse_pts` / `stop_swap` / `insurance_used`) | -| `level` | 关卡域对象 | 进关 `= {}` | `adventure_runner.gd:840-842` 硬编码名单 | +| `level` | `LevelRunner.level_counters` 公开成员 | 进关随宿主 new 天然空 | `adventure_runner.gd:840-842` 硬编码名单 | | `adventure` | `run_ledger.adventure_counters`(沿用) | 新冒险置空(`adventure_runner.gd:255`) | `domain=adventure`(4 枚:`twin_digs` / `pain_layers` / `tree_sense_sharp_used` / `tree_sense_guard_used`) | 🔴 **枚数订正**:现役 distinct counter_id **共 16 枚**(4+8+4),非草案初版的「13 枚」。13 系卡② 落地前的旧数(未含 `insurance_used`),且与草案自身分桶子项相加(4+8+4=16)自相矛盾。 **寿命语义不再需要任何字段**:对象活着值就活着,对象重建值自然归零。 -### 3.2 引擎接口改动 +### 3.2 引擎接口改动(2026-10-20 定稿——写口形态见 §7.10.8) | 现在 | 之后 | |---|---| -| `dispatch(event, payload, facts)` | 增 ctx 参数(携带本战可读写计数器容器引用集) | -| `counter()` | 改从 ctx 读(纯查询,不存) | -| `counter_add()` / `counter_spend()` | **删除**——写由发射点落到传入计数器容器 | +| `dispatch(event, payload, facts)` | `dispatch(ctx, event, payload, facts)`——ctx=`EffectContext` 四桶引用束(§7.10.1),每战构造一次 | +| `counter()` | `counter(ctx, counter_id)`(纯查询读 ctx,引擎不自持——N5) | +| `counter_add()` / `counter_spend()` | **实例方法删除**;改**静态纯函数**(ctx 首参)——7 个施加点调用形不变、语义单点(§7.10.8) | | `counters_export()` / `counters_seed()` | **删除** | | `has_effect_on()` / `validate_trigger_row()` | 保留(纯函数) | -| — | 新增纯函数 `bucket_of(counter_id)`(按前缀判桶) | +| — | 新增 `EffectContext` 类(`game/core/effect_context.gd`,四桶引用束字段)+ `static bucket_of(ctx, counter_id)`(前缀→目标桶字典,解析单点) | -写口迁移(**共 6 处,非 5 处**):`action_economy.gd:110/113/173`、`damage_controller.gd:351/464`、**`grant_segment.gd:327`** 由 `_fx.counter_add(...)` 改为对 ctx 计数器容器写入;`battle_orchestrator.gd:717` 的 `counter_spend` 同理。 +round_start 清零点保留在引擎 `dispatch` 特判内(`:210-212` 现役挂点),由按名单清零泛化为 `ctx.round_bucket.clear()`——前缀分桶后名单集合≡整桶键集,行为逐位等价(挂点不挪的依据见 §7.10.1)。 + +写口迁移(**共 7 处**:action_economy.gd `:108/:111/:169`、damage_controller.gd `:351/:464`、grant_segment.gd `:327`(`_apply_counter_hit`——卡② 保险写入唯一通路)、battle_orchestrator.gd `:714`(counter_spend,受理闸))由 `_fx.counter_add(...)` 改为静态 `EffectEngine.counter_add(ctx, ...)`;调用点行号系 2026-10-20 实查(草案初版 :110/:113/:173/:717 系 +2/+4 行漂移,A6 补列面见 §7.10.6)。 🔴 `grant_segment.gd:327` 是**卡② 完美保险的写入计数唯一通路**(`:315` `_apply_counter_hit(h)` 落 `insurance_used`),漏掉它=保险「每战限次一次」失效(恒 0 → 每次标错都豁免)。 @@ -124,14 +127,14 @@ | T | 内容 | 估时 | |---|---|---| | T0 | worktree/分支;冒烟·单元·探针·三闸基线记档 | 0.25d | -| T1 | 桶承载对象新建 + 四宿主接线 | 0.5–1d | -| T2 | 引擎删状态 + `dispatch` 增 ctx + `bucket_of` | 0.5–1d | -| T3 | 施加点改写(action_economy / damage_controller / orchestrator) | 0.5–1d | -| T4 | 三处清零点就位(轮始 / 进关 / 战斗 new) | 0.25–0.5d | -| T5 | 前缀校验进 `validate_trigger_row` | 0.25d | -| T6 | 数据行与树合成行 counter_id 调整 | 0.25d | -| T7 | **机制正向验收断言新增** + 旧测试迁移 + 变异验证 + 同种子复放对拍(详见 §4.1) | 1–1.5d | -| T8 | 文档回写(architecture / 06 / README / entities.yaml) | 0.25d | +| T1 | `EffectContext` 新建 + 四宿主接线(编排器两桶成员/ctx 挂载、LevelRunner 桶成员+enc 下传、set_fx 三处扩参) | 0.5–1d | +| T2 | 引擎删状态 + `dispatch`/`counter` 增 ctx + 写口改静态纯函数 + `bucket_of` | 0.5–1d | +| T3 | 7 个施加点改写(action_economy ×3 / damage_controller ×2 / grant_segment ×1 / orchestrator spend ×1)+dig_combo 死路删除 | 0.5–1d | +| T4 | 轮始清零泛化(引擎 round_start 特判整桶清空;进关/战斗 new 两处免费——§7.10.1) | 0.25d | +| T5 | 前缀校验双落点(`validate_trigger_row` + `_push_trigger`) | 0.25d | +| T6 | 数据行与树合成行 counter_id 调整(改名 4 处+`domain`/`reset_at` 键删除) | 0.25d | +| T7 | **机制正向验收断言新增** + 旧测试迁移 + 变异验证 + 同种子复放比对(详见 §4.1/§7.10.12) | 1–1.5d | +| T8 | 文档回写(architecture 反哺点归 06 条目 / 06 状态推进 / README / 卡片关联同步面) | 0.25d | ### 4.1 验收测试清单(机制正向验收 —— 主力) @@ -139,91 +142,96 @@ > > 对拍只能证「除已知差异外没改坏别的」(负向/兜底),**不能证新机制按设计工作**。机制改动的正向验收必须由下列断言承担。依据:`test-conventions.md` §1「存在必须证明可达且正确」/§3「缺陷修复必须沉淀回归断言」/§5 落码规范/§6 变异验证。 +> 🔴 **编号辨析**:本表验收点编号(A1–H1)与 §4.4 缺口编号(A1–A8)是两套命名空间,互不指涉——本表编号沿用 2026-10-19 首版验收清单,§4.4 编号沿用缺口盘点,改表不改号(卡内引用以「§4.1 V-」前缀消歧,写卡时逐条带编号尾缀)。 +> +> 🔴 **2026-10-20 定稿**:本表按 §7.10 闭合定值改写——A1 注入口径(§7.10.10)、B2 构造路径(§7.10.13)、D1 载体(§7.10.5)、E2 撤销并入 F1(§7.10.3)、G1 分组判读(§7.10.12)、新增 H1 旧档加载(§7.10.15)。 + | # | 验收点 | 执行载体 | 断言词汇 | 怎么测(注入粒度) | |---|---|---|---|---| -| **A1** | **adventure 桶跨战持久**(=`run_ledger.gd:42` 缺陷消解的**回归断言**,修前恒 0) | 冒烟 `smoke_all.gd` 冒险段 | 状态/计数器断言 | 新冒险开局 → 第 1 战末置 `adv_twin_digs=1` → 进入第 2 战首读该键 ==1 | -| **A2** | adventure 桶新冒险置空 | 冒烟 | 状态/计数器断言 | `start_adventure` 后桶 size==0 | +| **A1** | **adventure 桶跨战持久**(=`run_ledger.gd:42` 缺陷消解的**回归断言**,修前恒 0) | 冒烟 `smoke_all.gd` 冒险段 | 状态/计数器断言 | 两编排器共享同一 `RunLedger`(V25 同构):第 1 战 `orch1.action_economy.request_dig(0, false)` 真实挖一次(无返还,`adv_twin_digs`=1)→ 第 2 战(同 ledger 起 orch2)再挖一次(mod_eq 预评估读持久值判「第 2 次」→ 返还成立+桶值 2)——读/写两路径均走真实事件面(§7.10.10) | +| **A2** | adventure 桶新冒险置空 | 单测 `feat_vouchers_test.gd`(start_adventure 先例 `:25`) | 状态/计数器断言 | `start_adventure` 后 `run_ledger.adventure_counters` 为空 | | **A3** | adventure 桶随断点往返 | 单测 `feat_vouchers_test.gd`(承 V16,键名随前缀改) | 快照比对 | 写断点 → 回读 → 桶内容逐位相等 | -| **B1** | level 桶**同关跨战保持、进关清零** | 冒烟 | 状态/计数器断言 | 同关第 2 战读 `lvl_tree_sense_*` 保持;进下一关后归零 | -| **B2** | **tree_sense 每关限 2 次**(削弱行为的正面确认) | 冒烟 | 状态/计数器断言 | 同关第 1 战用满 2 次 → 第 2 战 `lt 2` 不命中 → 无减伤/无返还(修前第 2 战仍有额度) | -| **C1** | battle 桶随宿主销毁 | 冒烟 | 状态/计数器断言 | 第 1 战置 `insurance_used=1`;第 2 战读 ==0 | +| **B1** | level 桶**同关跨战保持、进关清零** | 冒烟 | 状态/计数器断言 | 两编排器经 enc["level_counters"] 共享同一字典(LevelRunner 真实下传形态):第 2 战读 `lvl_tree_sense_*` 保持;新 LevelRunner(进下一关形态)新桶天然为空(§7.10.11) | +| **B2** | **tree_sense 每关限 2 次**(削弱行为的正面确认) | 冒烟 | 状态/计数器断言 | B1 同款共享桶两编排器:第 1 战两次 `_fx.dispatch(ctx, "mine_hit", {})` 命中(damage_mult+counter_add 双行,桶值=2)→ 第 2 战同 dispatch 返回空(lt 2 闸关)且桶值不动——when 只读 counter fact、零 payload 依赖(§7.10.13) | +| **C1** | battle 桶随宿主销毁 | 冒烟 | 状态/计数器断言 | 第 1 战置 `insurance_used=1`;第 2 战(新编排器)读 ==0 | | **C2** | 完美保险「每战限次一次」仍成立(卡② V25 迁移保绿) | 单测 `feat_vouchers_test.gd:132+` | 状态/计数器断言 | 沿用 V25 注入口径,改走新桶 | -| **D1** | round 桶轮始清空 | 单测/冒烟 | 状态/计数器断言 | 轮始后 `round_*` 全 0 | -| **E1** | counter_id 无前缀或带 `meta_` 前缀 → **加载致命** | 单测(新增) | fail-fast | 合成一行喂 `validate_trigger_row` → 命中止/assert | -| **E2** | 同 counter_id 跨前缀重复 → 致命 | 单测(新增) | fail-fast | 同上 | -| **F1** | 旧件零残留 | 静态扫描面 | 快照比对 | 全仓 `counters_export` / `counters_seed` / `_reset_tree_limited_counters` 零命中 | -| **F2** | **旧断言同批摘除**(test-conventions §5.5 换代同生死) | — | — | `effect_words_t1_test.gd:86-94`、`smoke_all.gd:6083-6090`、`:6131-6134` 随旧件同批删除——旧件断言残留=假绿来源 | -| **G1** | 同种子复放对拍(**兜底,非主力**) | `adventure_monte_carlo` 同种子重放 | 重放 | 除已记档的已知差异外逐位一致;零局新采集(配套纪律③) | +| **D1** | round 桶轮始清空 | 冒烟 | 状态/计数器断言 | round 桶直写非零 → `orch._emit_round_start()`(真实发射函数 `:97`,§7.10.5)→ 全零 | +| **E1** | counter_id 带非法前缀(`meta_` 等)→ **加载致命**;树合成行同规则 | 单测(新增负面套件,manifest 登记)+`_push_trigger` assert 面 | fail-fast | 夹具表注入坏前缀行喂 `load_tables` → 拒绝(reward_dangling_treasure_test 同构 expect 1);合成路径坏前缀走 rebuild assert | +| **F1** | 旧件零残留(含旧 id 字面) | `static_scan.sh` 新增 S 段 | 快照比对 | 全仓 `counters_export` / `counters_seed` / `counters_merge_export` / `_reset_tree_limited_counters` 零命中 + **带引号旧 id 字面** `"tree_sense_sharp_used"` / `"tree_sense_guard_used"` / `"twin_digs"` / `"instinct_atk"` 零命中(带引号匹配不误伤 `"lvl_tree_sense_sharp_used"` 等新名——E2 撤销后的改名完整性防线,§7.10.3) | +| **F2** | **旧断言同批摘除**(test-conventions §5.5 换代同生死) | — | — | `effect_words_t1_test.gd:77-94`(export/seed 往返块)、`:96-124`(reset_at/counter_spend 块,随字段删除重写为桶语义)、`smoke_all.gd:6076-6083`(counter_add+export/seed 链)、`:6124-6128`(直呼 `_reset_tree_limited_counters`)、`:1419-1602` 裸引擎段 17 处 dispatch+8 处 counter_add 直调(改 ctx 形态)——旧件断言残留=假绿来源 | +| **G1** | 同种子复放比对(**兜底,非主力**;分组判读制) | `adventure_monte_carlo` 同种子重放 | 重放 | 锚内 normal 档前 20 种子(81000–81019,配套纪律③子集 ≤20):未受影响局全字段逐位一致;受影响局(保守超集=装备集含双管镐/sense 两组且 `mine_hits>0` 或 `seal_miss>0`)输入面字段恒等+`levels_cleared` 分布不得上行(§7.10.12) | +| **H1** | 旧档断点加载不崩(B4 补条) | 单测 `feat_vouchers_test.gd`(V16 旧档同构先例 `:124-127`) | 快照比对 | 旧断点 `adventure_counters` 含旧键(`tree_sense_sharp_used`=2 等)→ `resume_adventure` 受理零崩溃,旧键留桶成死键(无迁移——2026-10-18 先例) | **变异验证必做项**(test-conventions §6——无变异红记录只写「已实现,拦截能力未证」): | 断言 | 变异注入点 | 期望 | |---|---|---| -| A1 | 把 adventure 桶写入改回「判空早退」(复刻 `run_ledger.gd:42`) | A1 必须红 | -| B2 | 摘掉进关清零点(T4 产物) | B2 必须红 | +| A1 | begin_battle 挂载 ctx 时把 adventure 桶引用换成新建空字典(复刻「副本不同步/判空早退」缺陷类——§7.8 守卫原形的同构形态) | A1 必须红 | +| B2 | 两编排器改传各自新建 level 字典(复刻 `:840-842` 旧形态「跨关不清理、每战重置」) | B2 必须红 | | E1 | 注释掉 `validate_trigger_row` 内的前缀校验分支 | E1 必须红 | +| F1 | 任一源文件临时写回一处带引号旧 id 字面(如 `"counters_export"` 调用形) | F1 扫描必须红 | > 三步闭环:注入 → 只跑覆盖该断言的最窄一道闸 → `git checkout -- <文件>` 精确还原并复跑回绿 → 逐条进实现报告变异验证记录表。 **真人目检登记**:tree_sense 锋/守由「每战限 2 次」变「每关限 2 次」是玩家可感知削弱 ⇒ 按「只登记不阻塞」登记进 `07-体验验证清单`,不构成收口前置。 -### 4.2 载体可达性核验(2026-10-19 实查,逐条对 §4.1) +### 4.2 载体可达性核验(2026-10-20 复核轮全绿——逐条对 §4.1) -> test-conventions §5:「写卡期查不出执行载体的条目=不可测,当场呈报,禁拖到实现期」。下表是逐条实查结果。 +> test-conventions §5:「写卡期查不出执行载体的条目=不可测,当场呈报,禁拖到实现期」。下表 2026-10-19 首查,2026-10-20 复核轮六项未闭合项全部闭合(定值见 §7.10)。 | 验收点 | 载体 | 核验结论 | 证据(file:line) | |---|---|---|---| | **C2** 保险限次一次 | 单测 `feat_vouchers_test.gd` | ✅ **已闭合**——V25 现成「第 1 战用满 → 第 2 战重新豁免」双编排器骨架;`orch2.begin_battle({"battle_index":2,…})` + `orch2._grant_seg._judge_seal(...)` 即真实 `seal_missed` | `:143-186` | -| **E1/E2** 前缀致命 | 新增负面套件 | ✅ **已闭合**——现役 fail-fast 测试模式:`config_db_fatal_oob_test.gd`(独立进程,`expect:1` + `negative:true`),manifest 协议在役 | `tests/run_all.gd:37`/`:48` | -| **F1** 旧件零残留 | `static_scan.sh` 新增 S 段 | 🟡 **半闭合**——S1–S10 分检制在位;本批新增 S 段承载,按纪律「闸件增减只改该脚本+`run_all_gates.sh` 登记」,卡里须写明改哪两个文件 | `static_scan.sh:38-82` | -| **A1/A2/A3** adventure 桶 | 冒烟/单测新段 | 🟡 **半闭合**——RunLedger 经 `enc["ledger"]` 下传(`battle_orchestrator.gd:375`),冒烟可自建共享计数器容器喂两个 orch;`AdventureRunner.run_ledger` 公开字段可达(`smoke_all.gd:6131` 先例)。**卡在 U2** | `battle_orchestrator.gd:375` | -| **C1** battle 桶 | 单测/冒烟 | 🟡 **半闭合**——编排器可 new + begin_battle(`smoke_all.gd:2680-2687` 先例);桶须为公开字段或 API,测试才读写得了 | `smoke_all.gd:2680-2687` | -| **B1/B2** level 桶 | 冒烟新段或探针 | 🟡 **半闭合**——LevelRunner 真实驱动有先例(`board_shot_probe.gd:5`);但现役 level 桶**寄居在 `run_ledger.adventure_counters` 字段内**(`adventure_runner.gd:840-842` erase 的就是该字段),搬去 LevelRunner 后须新定公开接口。**卡在 U3** | `adventure_runner.gd:840-842` | -| **D1** round 桶 | 冒烟 | 🔴 **未闭合**——`round_start` 的真实发射入口未定位 | — | -| **G1** 对拍已知差异 | `analyze.py` 字段 | 🔴 **未闭合**——RUNSUM 哪些字段会变未列 | — | +| **E1** 前缀致命 | 新增负面套件 | ✅ **已闭合**——现役 fail-fast 测试模式:`config_db_fatal_oob_test.gd`(独立进程,`expect:1` + `negative:true`)、`reward_dangling_treasure_test.gd`(夹具表注入→load_tables 拒绝)双先例,manifest 协议在役 | `tests/run_all.gd:37`/`:48` | +| **F1** 旧件零残留 | `static_scan.sh` 新增 S 段 | ✅ **已闭合**——S1–S10 分检制在位;本批新增 S 段承载(旧件符号+带引号旧 id 字面两组规则),改面锁定两文件=`static_scan.sh`+`run_all_gates.sh` 登记(域划分唯一出处) | `static_scan.sh:38-82` | +| **A1/A2/A3** adventure 桶 | 冒烟/单测新段 | ✅ **已闭合**——两编排器共享同一 `RunLedger`(V25 骨架)+写入走真实 `request_dig`(U2 随战末导出消失而解除,§7.10.4);`RunLedger` 公开字段直读直写先例在役 | `feat_vouchers_test.gd:175-187`、`smoke_all.gd:6124` | +| **C1** battle 桶 | 单测/冒烟 | ✅ **已闭合**——编排器可 new + begin_battle(`smoke_all.gd:2680-2687` 先例);桶=编排器公开成员字段,测试直读(§7.10.2) | `smoke_all.gd:2680-2687` | +| **B1/B2** level 桶 | 冒烟新段 | ✅ **已闭合**——LevelRunner 直构在役(`smoke_all.gd:6130` `level_runner.gd.new(_db, rng)`);桶=`LevelRunner.level_counters` 公开成员(U3 解,§7.10.11),enc["level_counters"] 下传接线照抄 `"ledger"` 行 | `smoke_all.gd:6130`、`level_runner.gd:466-477` | +| **D1** round 桶 | 冒烟 | ✅ **已闭合**——`round_start` 真实发射点定位=`_emit_round_start()`(U4 解,§7.10.5);直呼该函数即真实路径 | `battle_orchestrator.gd:97`(调用点 `:425`/`:1077`) | +| **G1** 同种子复放比对 | `adventure_monte_carlo` 重放 | ✅ **已闭合**——RUNSUM 27 字段清点完毕(`adventure_monte_carlo.gd:114-149`),分组判读制与允许差异面定值(U5 解,§7.10.12) | `adventure_monte_carlo.gd:114-149` | -### 4.3 写卡前未闭合项(禁拖到实现期) +### 4.3 写卡前未闭合项(2026-10-20 全部闭合——定值与推导见 §7.10) -| # | 未闭合项 | 具体卡点 | +| # | 原卡点 | 闭合定值(详据→§7.10) | |---|---|---| -| **U1** | **A1 注入口径写错了** | 原稿写「置 `adv_twin_digs=1`」**不可行**——新形态引擎无 `counter_add` 公开写口(T2 删除),置数必须走**真实事件**(如触发一次 `dig_paid`)。这条必须重写 | -| **U2** | `_battle_over` 能否孤立调用 | 战末入口在 `battle_orchestrator.gd:1111`(私有)。直接调它会连带 despawn/映射退役/奖励结算。要确认能否被测试单独调用,或另找更窄的战末钩子 | -| **U3** | level 桶公开接口 | LevelRunner 持桶后,测试读写走什么(公开字段/getter/方法)——不定这条,B1/B2 就不可测 | -| **U4** | `round_start` 真实发射入口 | 未定位;定位不到,D1 只能走裸 `dispatch`(弱于真实路径) | -| **U5** | G1 已知差异字段清单 | 需列出 RUNSUM 中预期变化的具体字段,否则对拍红了无法区分「预期」与「意外」 | -| **U6** | B2 的 `mine_hit` 构造路径 | `seal_missed` 有 V25 的 `_judge_seal` 先例;`mine_hit` 的等价构造路径未定位 | +| **U1** | A1 注入口径写错(引擎无 counter_add 公开写口) | 改走真实 `dig_paid` 路径:`orch.action_economy.request_dig(0, false)` 一次即 +1(双管镐 counter_add 行无 when,`feats.tres:26-32` 实证);断言链含第 2 战返还判定,证明读路径同样走真实事件面(§7.10.10) | +| **U2** | `_battle_over` 能否孤立调用 | **不需要**——新形态下战末导出动作消失,A1 断言改走共享桶+两编排器(V25 同构),无验收点依赖该私有入口(§7.10.4) | +| **U3** | level 桶公开接口 | `LevelRunner.level_counters` 公开类型化成员,enc["level_counters"] 下传,测试直读直写(§7.10.11) | +| **U4** | `round_start` 真实发射入口 | 已定位=`battle_orchestrator.gd:97 _emit_round_start()`(调用点 `:425`/`:1077`);D1 直呼该函数即真实路径(§7.10.5) | +| **U5** | G1 已知差异字段清单 | RUNSUM 27 字段清点完毕,分组判读制:未受影响局逐位一致/受影响局输入面恒等+`levels_cleared` 不得上行(§7.10.12) | +| **U6** | B2 的 `mine_hit` 构造路径 | 两编排器共享 level 桶+各自 `_fx.dispatch(ctx, "mine_hit", {})` 直驱(sense 行 when 只读 counter fact,零 payload 依赖);`_facts_reveals` 捏造路径不取(§7.10.13) | -**结论**:13 条验收点中 **2 条已闭合**(C2/E1E2)、**4 条半闭合**(A1A2A3/C1/B1B2/F1)、**2 条未闭合**(D1/G1),另有 6 项卡点(U1–U6)必须先解。**§4.1 现阶段不可直接落码成卡的验收清单。** +**结论**:13 条验收点保持 13 行(E2 撤销并入 F1、新增 H1 补位),**全部载体闭合**,六项卡点全部定值。**§4.1 现在可整表落卡。** -### 4.4 实现设计缺口(2026-10-19 第三轮盘点——写卡前必须补) +### 4.4 实现设计缺口(2026-10-20 全部闭合——定值与推导见 §7.10) -| # | 缺口 | 具体未定 | 阻塞等级 | -|---|---|---|---| -| **A1** | **`ctx` 结构未定义**(最大缺口) | `dispatch` 增的 ctx 里装什么?四桶引用怎么命名/定型?**谁构造 ctx、多久构造一次**?——若 ctx 每轮重建,round 桶天然是新的 `{}`(清零点免费),但 level/adventure 引用要每轮重挂;若 ctx 每战构造一次,round 桶的清零点要显式做。两种走法决定了 T4「三处清零点」到底是三处还是两处 | 🔴 阻塞 | -| **A2** | 桶容器类型与测试接口 | 四桶是否统一为 `Dictionary[String, int]`?level/adventure 是宿主字段、ctx 只带引用——那测试凭什么读写(公开字段/getter/方法)未定(同 U3) | 🔴 阻塞 | -| **A3** | **树合成行走不到生产侧前缀校验** | `feats.tres`/`treasure_items.tres` 的行经 `validate_trigger_row`(`feat_table.gd:44`/`treasure_item_table.gd:104`);但**树合成行**(`effect_engine.gd:142-158`)走 `_push_trigger`,该函数只 `assert(EVENTS.has(on))` 校事件域,**对 counter_id 前缀零校验**。`tree_rules_v11_test.gd:60` 是测试在代校,不是生产在校 ⇒ 前缀校验必须同时落 `_push_trigger`,否则树规则写错前缀不致命,与「加载期强校验」的完成定义 5 直接冲突 | 🔴 阻塞 | -| **A4** | `_battle_over` 孤立调用(同 U2) | 战末入口私有(`orchestrator.gd:1111`),直接调连带 despawn/映射退役/奖励结算 | 🟡 | -| **A5** | `round_start` 真实发射入口(同 U4) | 未定位 ⇒ D1 可能只能走裸 `dispatch`,弱于真实路径 | 🟡 | -| **A6** | `counter_spend` 施加面漏列 | §3.2 只列了写口 `orchestrator.gd:717`;**漏了读施加面 `action_economy.gd:106`**(按 hits 的 `kind == "counter_spend"` 分支走加收对价)——ctx 改动后这条路径怎么走未写 | 🟡 | -| **A7** | counter_id 改名传播面未清点 | 已知:`feats.tres` 数据行、`effect_engine.gd` 树合成行硬编码、`smoke_all.gd` 断言字符串、`tests/` 断言字符串。**未查:呈现层/HUD 是否显示 counter_id**。T6 估时 0.25d 可能不够 | 🟡 | -| **A8** | 保险双计数一致性(N6 遗留) | `_perfect_forgiven`(编排器自持计数,N6 定「留编排器」)与 `insurance_used`(battle 桶,`grant_segment.gd:327` 写)是两份。V25 对两者都断言;`when counter lt 1` 读的是桶内那份 ⇒ 需厘清 `_perfect_forgiven` 是镜像还是另有语义,否则同一次标错可能被两处各写一次 | 🟡 | +| # | 原缺口 | 闭合定值(详据→§7.10) | +|---|---|---| +| **A1** | **ctx 结构未定义**(最大缺口) | `EffectContext` 纯引用束类(`game/core/effect_context.gd`,四桶 `Dictionary[Variant, Variant]` 字段、零方法);每战构造一次:编排器 `_init` 建并挂自有两桶、`begin_battle` 挂 adventure/level 两引用;round 桶清零留引擎 dispatch 特判(就地整桶清空,行为逐位等价)——T4 三处清零点=轮始一处+宿主 new 两处免费(§7.10.1) | +| **A2** | 桶容器类型与测试接口 | 四桶统一 `Dictionary[Variant, Variant]`(S9 现行口径);测试接口=宿主公开字段直读直写(§7.10.2,同 U3) | +| **A3** | **树合成行走不到生产侧前缀校验** | 前缀校验双落点:`validate_trigger_row`(.tres 路径→errs 加载致命)+`_push_trigger`(合成行 assert),共用同一静态判定函数;E2 撤销(无指称),改名完整性防线归 F1 带引号旧 id 字面零命中(§7.10.3) | +| **A4** | `_battle_over` 孤立调用(同 U2) | 阻塞消解——无验收点依赖(§7.10.4) | +| **A5** | `round_start` 真实发射入口(同 U4) | 已定位 `:97 _emit_round_start()`(§7.10.5) | +| **A6** | `counter_spend` 施加面漏列 | `action_economy.gd:103-108`(dig_paid 加收对价+积计数分支)列入迁移面;行号漂移订正(§7.10.6) | +| **A7** | counter_id 改名传播面未清点 | 呈现层零引用(全目录检索实证),传播面收窄至数据行/引擎字面/测试断言三面,T6 估时维持(§7.10.7) | +| **A8** | 保险双计数一致性 | 厘清=**同点双记各司其职**(`_perfect_forgiven` 供判定段两账相减、`insurance_used` 供 when 限次闸),无重复写风险;本批零改动,卡内立「不改面」条目(§7.10.9) | -### 4.5 需求澄清未对齐(不影响本批动工,但需登记或后续裁) +### 4.5 需求澄清项(2026-10-20 全部落处置——B1/B2 本轮执行,B6 按 §7.10.14 定值) -| # | 事项 | 现状 | 处置 | -|---|---|---|---| -| **B1** | **立项依据无文档载体** | 「系统无状态」在 `architecture.md`/`architecture.yaml`/`entities.yaml` **零命中**;本批是代码批、禁写 `design/` ⇒ 卡片的立项依据只能引用「用户 2026-10-19 会话裁定」,不是文档级依据 | 登记 06(来源=会话提及,设计面=文档轨)→ 后续文档批补 architecture.md 条目;本批报告里作反哺点 | -| **B2** | **06:627 条目解法方向被推翻** | 「计数器寿命域未统一」条目的解法(寿命域统一口径)已被本提案推翻,但 06 是待办唯一登记处,**条目不改,后人看 06 仍会按旧方向想** | 同上,登记 06 改写/作废;本批只作反哺点 | -| **B3** | 天赋树锋/守是否重新定价 | 本批把它从「每战 2 次」修回「每关 2 次」=削弱(§7.7) | 已定不改数值;「是否重新定价」=独立议题,不进本批 | -| **B4** | 旧档断点旧键失效 | `tree_sense_*`→`lvl_*` 后旧档内旧键成死键 | 已按 2026-10-18 先例定不迁移;**但卡的验收应加一条「旧档加载不崩」**(现在没有) | -| **B5** | `roadmap.md` 当前位 stale | 仍写「迭代 31 待开工」,卡②已合入 | 已呈报,不进本批 | -| **B6** | `_fx.counter("dig_combo")` 死读数 | `orchestrator.gd:641`,无任何数据行声明该 id ⇒ combo 加成恒 0 死路 | 已呈报。**建议本批顺手删**(迁到 ctx 后仍恒 0,删它零风险),需你一句确认 | +| # | 事项 | 处置(执行状态) | +|---|---|---| +| **B1** | **立项依据无文档载体** | ✅ **本轮已执行**——新增 06 条目「效果引擎系统无状态原则缺架构文档条目」(文档轨·待文档设计),后续文档批补 architecture.md「架构原则」条目;实现批报告仍作反哺点。§10.3 所引 `design/registry/` 两 yaml 已随 2026-10-19 用户裁注销删除,该节对 yaml 的引用失义、以本条为准;立项判据=§7.9 #1(用户 2026-10-19 ECS 架构裁定) | +| **B2** | **06:627 条目解法方向被推翻** | ✅ **本轮已执行**——06「计数器寿命域未统一」条目已改写(现状换代=无状态化重构方向、补「寿命域统一口径」方案作废因由并指向本提案;状态推进「文档设计已闭合+待写卡」)——后人从 06 进入即见新方向 | +| **B3** | 天赋树锋/守是否重新定价 | **已闭合**——本批把它从「每战 2 次」修回「每关 2 次」=削弱(§7.7);不改数值,「是否重新定价」=独立议题不进本批(无需登记——现值非缺陷非待办,若用户日后提起再立条目) | +| **B4** | 旧档断点旧键失效 | **已闭合**——按 2026-10-18 先例定不迁移;验收已补 **H1 旧档加载不崩**(§4.1、§7.10.15) | +| **B5** | `roadmap.md` 当前位 stale | **已呈报在案**,归并行会话,不进本批不动 | +| **B6** | `_fx.counter("dig_combo")` 死读数 | **定值=本批删除**(§7.10.14——全仓无声明行实证+位点本批必触+零行为差;原文「需一句确认」按约束推导闭合,可否决) | --- ## 5. 影响面 -**代码**:`effect_engine.gd`、`battle_orchestrator.gd`、`action_economy.gd`、`damage_controller.gd`、`reward_economy.gd`(`set_fx` 面)、**`settlement/grant_segment.gd`**(草案初版漏——6 个用点:`:103` 读 / `:205` 读 / `:227` `has_effect_on` / `:311-317` `forgive_seal_miss` 消费 / `:327` 写)、`run_ledger.gd`、`adventure_runner.gd`、`level_runner.gd`、`feats.tres`。 +**代码**:`effect_engine.gd`、**`effect_context.gd`(新建——ctx 引用束,§7.10.1)**、`battle_orchestrator.gd`(两桶成员+ctx 构造挂载+dig_combo 死路删除)、`action_economy.gd`、`damage_controller.gd`、`reward_economy.gd`(`set_fx` 面扩 ctx 参——三处注入点 `battle_orchestrator.gd:280-282`)、**`settlement/grant_segment.gd`**(草案初版漏——6 个用点:`:103` 读 / `:205` 读 / `:227` `has_effect_on` / `:311-317` `forgive_seal_miss` 消费 / `:327` 写 / `:54/:61/:62` combo_cap 收集随死路删除)、`run_ledger.gd`(`counters_seed_snapshot`/`counters_merge_export` 随搬运链删除)、`adventure_runner.gd`、`level_runner.gd`(`level_counters` 成员+enc 下传)、`feats.tres`、`data/schemas/feat_table.gd`/`treasure_item_table.gd`(校验调用面零改——前缀校验在 `validate_trigger_row` 内部生效)。 **测试**(草案初版漏项已补): @@ -234,8 +242,9 @@ | `feat_vouchers_test.gd` | **`:114`/`:119`/`:128`**(V16 断点往返 `pain_layers`/`twin_digs`;初版写 `:92-103` 系错行)+ `:132+` 卡② V25 完美保险验收组 | | `settle_segments_test.gd` | `:32-33` `_apply_counter_hit` + `_fx.counter("dig_combo")` | | `treasure_effects_test.gd` | `:34/:45/:53-56` 裸 `dispatch` 面(无 ctx 参数则签名不兼容) | -| `smoke_all.gd` | `:6083/:6085/:6088` `counter_add`+`counters_export`+`counters_seed`/`:6131-6134` 直呼 `_reset_tree_limited_counters`(删函数须同步)/**另 8 处 `fx.counter_add` 直调 `:1427/:1436/:1445/:1466/:1478/:1525/:1566/:1583`(初版全漏)**/`:1410` 断点 `adventure_counters` 键断言/`:1612` `_fx.rebuild`/`:6096/:6124/:6148/:6157` enc 携带 `adventure_counters` 空容器 | -| `run_all.gd` | 套件表(增改套件须登记) | +| `smoke_all.gd` | `:6076-6083` `counter_add`+`counters_export`+`counters_seed` 链/`:6124-6128` 直呼 `_reset_tree_limited_counters`(删函数须同步)/**`:1419-1602` 裸引擎段 17 处 `dispatch`+8 处 `counter_add` 直调(改 ctx 形态——冒烟 rig 自建 ctx 或用 `orch.counters_ctx`)**/`:1410` 断点 `adventure_counters` 键断言/`:1612` `_fx.rebuild`/`:6086-6156` 各 rig enc 携带 `"adventure_counters"` 死键(迭代 27 收口前旧形态残留——编排器只读 `enc["ledger"]`,`battle_orchestrator.gd:372` 实证;同批顺手清键) | +| `run_all.gd` | 套件表(**新增 E1 负面套件登记**) | +| `settle_segments_test.gd` | `:32-33` `_apply_counter_hit` 样本 id `dig_combo` 随死路删除换活 id(§7.10.14) | **存档/断点**:`adventure` 桶已在断点(写键 `adventure_runner.gd:1035`,续玩回填 `:206-208`);`level` 桶是否进断点见 N3。仅改归属不改 id → 旧档零影响;**若采纳 N2 前缀改名(`tree_sense_*` → `lvl_*`)则旧档断点内旧键失效**(Alpha 阶段可接受,有先例:代码术语刷新批 2026-10-18 用户裁不迁移)。 @@ -427,6 +436,99 @@ func counters_merge_export(exported): --- +### 7.10 写卡前缺口闭合定值(2026-10-20 复核轮——由既有裁定与硬纪律推得) + +> 本节把 §4.3 六项卡点、§4.4 八项实现设计缺口、§4.5 六项需求澄清一次闭合。逐项给「定值+推导依据」,全部不占用裁决位——依据三源:用户已裁方向(2026-10-19 ECS 架构裁定、N1–N6 定值)、项目硬纪律(code-conventions/test-conventions/doc-conventions)、本仓代码实证(2026-10-20 逐点实查,file:line 在案)。若与你的判断不符,指出即推翻(同 §7.9 口径)。 + +#### 7.10.1 A1——ctx 结构定值 + +**定值**:ctx=新建纯引用束类 `EffectContext`(`game/core/effect_context.gd`,RefCounted),四个公开类型化字段 `round_bucket`/`battle_bucket`/`level_bucket`/`adventure_bucket`(各 `Dictionary[Variant, Variant]`,int 值),零方法零行为。**每战构造一次**:编排器 `_init` 建 ctx 并挂入自有两桶引用;`begin_battle` 挂入 adventure(`_ledger.adventure_counters`)与 level(enc 新键 `"level_counters"`,LevelRunner `_start_battle` 下传)两引用;ctx 以编排器公开成员 `counters_ctx` 在役——段类经 `oc` 引用即达;三协同件(action_economy/damage_controller/reward_economy)经现役 `set_fx` 注入面扩一参收同一 ctx 引用(后续挂载是同对象内字段赋值,注入时序无感)。 + +**推导依据**: +- 「每战一次」唯一:ctx 持桶**引用**且 round 桶清零用**就地清空**,则每轮重建 ctx 毫无收益、徒增重挂面。「每轮重建则 round 桶免费清零」的备选不成立——它把 level/adventure 引用变成每轮重挂的高频面,换来的只是把一处 `.clear()` 挪进构造。 +- round 桶清零点**留在引擎 `dispatch` 特判内**(`effect_engine.gd:210-212` 现役挂点),由按名单清零泛化为 `ctx.round_bucket.clear()`:前缀分桶后 round 桶内键集≡现役名单集合,行为逐位等价。挂点不挪的依据=现役语义是「重置随事件发生」而非「随发射位点发生」——裸 `dispatch("round_start")` 路径(冒烟 `:6060`/`:1573` 先例)依赖此语义。⇒ **T4「三处清零点」定为:轮始一处(引擎特判泛化)+战斗 new/进关 new 两处免费(宿主 new 天然空桶)**。 +- 「类」而非裸 Dictionary:RunLedger 先例(审计 P1-4 收口)已把「函数签名上不可见的共享可变引用」换成签名可见的显式类;ctx 跨四类边界传递(编排器→引擎→三协同件),code-conventions §2.2 跨层标识符语义成文 ⇒ 显式类。S9 类型闸下裸 `Dictionary` 参数只有 `Dictionary[Variant, Variant]` 注解可走且键名无校验,类字段即自文档。 +- 熵增闸不触:`tools/repo_structure_audit.py` 六查只巡顶层目录/根文件/图像白名单/退役路径/design 子目录/art 内容,`game/core/` 内新增 .gd 不触任何一查(§11 N1 甲「①熵增闸要求新类同批修订白名单」的顾虑经实查不成立于 core 内新文件——该顾虑不再构成「不新建类」的理由,但 N1 定值照旧:桶宿主挂编排器、ctx 只是参数面引用束,两者不冲突)。 +- 字段名取 `round_bucket` 族:`round` 会遮蔽 GDScript 内建函数 `round()`。 + +#### 7.10.2 A2——容器类型与测试接口定值 + +**定值**:四桶统一 `Dictionary[Variant, Variant]`(int 值;S9 现行口径「账本类字典标注 `Dictionary[Variant, Variant]` 即合格」,元素类型精化不入硬纪律)。测试读写接口=**宿主公开字段直读直写**:round/battle 桶=`BattleOrchestrator` 两个公开成员(`fx_counters_round`/`fx_counters_battle`,ctx 构造时挂引用,与 ctx 内字段同物异名同字典);level 桶=`LevelRunner.level_counters` 公开成员;adventure 桶=`RunLedger.adventure_counters`(现役字段名不动,§7.9 #3)。 + +**推导依据**:test-conventions §5.4 调试注入=测试代码直调核心层写口(直改计数器/存档域)——公开字段直写是该条现行承载形态(冒烟 `:6124` `ar.run_ledger.adventure_counters = {...}`、V16 `:114` 同款在役先例);「公开字段 vs getter vs 方法」三候选中后两者无任何约束要求,最小改动取字段。 + +#### 7.10.3 A3——前缀校验双落点定值(E2 并入 F1) + +**定值**:前缀合法性校验落两处、共用同一静态判定函数——①`validate_trigger_row`(.tres 行路径):`do` 含 `counter_id` 时校前缀(无前缀=合法 battle;`round_`/`lvl_`/`adv_` 合法;`meta_` 及其余未知前缀→errs 追加违例,加载致命);②`_push_trigger`(树合成行路径):同规则 assert,写错即调试期致命。**E2 撤销**:「同 counter_id 跨前缀重复」在新形态下无指称——前缀即归属,同一字符串必落同一桶,「跨桶同名」不可构造;「同一语义计数器两行写了两套 id」(改名漏改一类)不可机器判定(两串本不同),其防线归 F1:静态扫描 S 段新增**带引号旧 id 字面零命中**规则(`"tree_sense_sharp_used"`/`"tree_sense_guard_used"`/`"twin_digs"`/`"instinct_atk"`——带引号匹配不误伤 `"lvl_tree_sense_sharp_used"`/`"adv_twin_digs"`/`"round_instinct_atk"` 等新名)。 + +**推导依据**:完成定义 5「写错即加载致命」对 .tres 行经 errs→load_tables 拒绝通道成立(feat_table.gd:44/treasure_item_table.gd:104 调用面零改、校验在函数内部生效);树合成行不经 .tres 校验、只在 rebuild 期经 `_push_trigger` 生成(`effect_engine.gd:142-158`),漏②=A3 原判「与完成定义 5 直接冲突」成立。负面套件载体=`reward_dangling_treasure_test.gd` 同构(copy_tables 夹具注入坏行→load_tables 拒→expect 1+negative:true,run_all.gd manifest 登记)。 + +#### 7.10.4 A4/U2——`_battle_over` 不再需要孤立调用(阻塞消解) + +**定值**:无任何验收点依赖 `_battle_over` 孤立可达。原判的隐含前提是「adventure 跨战持久仍靠战末导出、断言须在战末时点取值」;新形态下导出动作整体消失,写入经 ctx 就地落共享桶,A1 断言改为「第 1战中经真实事件写入共享桶 → 第 2 战 `begin_battle`(同 ledger)经引擎读/返还判定验值」(V25 两编排器同构)——跨战持久由结构保证(同一字典引用),战末时点无待测行为。 + +#### 7.10.5 A5/U4——`round_start` 发射入口已定位 + +**定值**:真实发射点=`battle_orchestrator.gd:97 _emit_round_start()`(调用点 `:425` 首轮/`:1077` 续轮)。D1 载体=冒烟直呼 `orch._emit_round_start()`——即真实发射函数本身,窄于完整轮切换;跨下划线直呼先例在役(V25 `_judge_seal`、冒烟 `:6125` `_reset_tree_limited_counters`)。 + +#### 7.10.6 A6——施加面补列与行号订正 + +**定值**:`action_economy.gd:103-108`(dig_paid 的 counter_spend 订阅施加=加收对价+积计数)列入 §3.2 迁移面——该分支的「读-判-写」序列逐字保留,仅写口改静态函数。行号订正(2026-10-20 实查):action_economy 三写口实为 `:108/:111/:169`(草案 :110/:113/:173 系漂移);orchestrator counter_spend 实为 `:714`(草案 :717)。 + +#### 7.10.7 A7——改名传播面清点完成 + +**定值**:呈现层零引用(`game/presentation/` 全目录检索 counter_id 与 16 枚 id 字面零命中)——呈现面不入改名传播。传播面收窄为三面:`feats.tres` 行(id 改名 4 处+`domain`/`reset_at` 键删除约 12 行)、`effect_engine.gd` 合成行字面与 DO_KEYS 常量、测试断言字符串(§5 表)。T6 估时 0.25d 维持。 + +#### 7.10.8 写口形态定值(§3.2 修订——静态纯函数) + +**定值**:`counter_add`/`counter_spend` **实例方法删除**,改**静态纯函数** `static func counter_add(ctx, counter_id, value, set_mode=false)`/`static func counter_spend(ctx, counter_id, value) -> bool`,与 `validate_trigger_row`/`bucket_of` 同类(零实例状态,完成定义 1 不受触)。桶解析单点=`static func bucket_of(ctx, counter_id) -> Dictionary`(按前缀返回目标桶字典,前缀规则唯一出处)。 + +**推导依据**:§3.2 原稿「写由发射点落到传入计数器容器」的直写形态作废——7 个施加点各自内联桶解析+算术会把「spend 阈值闸」「set_mode」语义复制七份,同种子复放对语义单点的要求不容许;用户 N2 裁定的红线是「引擎不持有状态」,静态函数无实例态不触红线;调用形与现役一致(`_fx.counter_add(...)` → `EffectEngine.counter_add(ctx, ...)`)使 7 个施加点 diff 收窄为加一参。 + +#### 7.10.9 A8——保险双账语义厘清(不改面契约) + +**定值**:`_perfect_forgiven`(编排器自有账)与 `insurance_used`(battle 桶)**非镜像、系同点双记各司其职**:同一标错事件同一分支内各写一次(`grant_segment.gd:314` forgiven 加一/`:315` `_apply_counter_hit` 落桶)——前者供判定段「两账相减」裁定(`perfect_sweep_earned`),后者供引擎 when `lt 1` 限次闸;无重复写风险(闸序:dispatch 仅在 `insurance_used<1` 时返回豁免命中,随后两写同分支各一次)。本批零改动(N6 已定留编排器);卡内立「不改面」条目:两账同点双记关系迁移后必须原样保持(V25 对两者都断言,迁移保绿即证)。 + +#### 7.10.10 U1——A1 注入口径重写(真实事件面) + +**定值**:A1 注入走真实 `dig_paid` 路径——`orch.action_economy.request_dig(0, false)`(核心写口直调,test-conventions §5.4 口径)。可行性实证:双管镐 counter_add 行**无 when**(`feats.tres:26-32`),一次 request_dig 即 `adv_twin_digs` 加一。断言链=第 1 战挖一次(无返还——mod_eq 预评估读 0;桶值 1)→ 第 2 战(同 ledger 起 orch2)挖一次(预评估读持久值 1 判「第 2 次」→ 返还成立+桶值 2)——**返还判定证明第 2 战引擎经 ctx 读到了第 1 战的持久值**,读写两路径均走真实事件面。前置核过:首轮 `notify_round_start` 后 Active 相位、基础 AP 覆盖 dig 基础价,两连挖无经济障碍。 + +#### 7.10.11 U3——level 桶测试接口 + +**定值**:`LevelRunner.level_counters` 公开类型化成员(`Dictionary[Variant, Variant]`),`_start_battle` enc 增 `"level_counters"` 键下传(`level_runner.gd:466-477` 照抄 `"ledger"` 行位置),编排器 begin_battle 挂入 ctx。B1/B2 载体=冒烟 LevelRunner 直构(现役先例 `:6130` `level_runner.gd.new(_db, rng)` 在役)+公开字段直读直写(§7.10.2 同口径)。 + +#### 7.10.12 U5——G1 已知差异面(分组判读制) + +**定值**:RUNSUM 字段面清点完毕(`adventure_monte_carlo.gd:114-149` 共 27 字段)。行为变更只触 adventure 桶四枚中的三枚——**pain_layers 迁 battle 对全新开局零位移**(缺陷态下本就不跨战〔§7.8 自锁〕,battle 桶同样不跨战,前后皆无跨战携带);受影响枚=`adv_twin_digs`(返还得真跨战累积)与 `lvl_tree_sense_*`(每战限 2 → 每关限 2,§7.7 削弱定性)。同种子复放比对判读分两组: + +| 组 | 判定条件(由 RUNSUM 自身字段可判) | 判据 | +|---|---|---| +| 未受影响局 | feat_mode=off,或装备集不含双管镐与 sense 两组 | **全字段逐位一致**(结构迁移对未触路径必须透明——零漂移回归面) | +| 受影响局 | 保守超集:装备集含受影响件且(`mine_hits>0` 或 `seal_miss>0` 或付费挖格≥2) | 输入面字段恒等(policy/seed/atk_pct/hp_pct/route/attune/equipped/feat_mode);其余字段允许 RNG 级联位移(轮数一变后续流消费全移);统计面判据一条:**`levels_cleared` 分布不得上行**(削弱批清关率上移即意外,§7.7 定性) | + +复验规模:锚内 normal 档前 20 种子(81000–81019,配套纪律③子集 ≤20;normal 单局 1.21s,20 局约 25 秒)。逐位差异明细随实现报告记档。 + +#### 7.10.13 U6——`mine_hit` 构造路径 + +**定值**:`mine_hit` 无单事件判定函数(发射内联在授予段 run 的 mine 分支 `grant_segment.gd:92`),B2 构造=**两编排器共享 level 桶+引擎 dispatch 直驱**:`enc["level_counters"]` 传同一字典引用(V25 两编排器同构+挂载路径同测),各自 `_fx.dispatch(各自ctx, "mine_hit", {})`——sense 行 when 只读 counter fact、零 payload 依赖,裸 dispatch 即完整真实判定路径。`_facts_reveals` 捏造路径**不取**:mine 分支连带 `_grant_routed` 极性行路由,捏造快照须伪造 cell_type 行集,脆且越过被测面。第 2 战 dispatch 返回空=「无减伤/无返还」断言本体(lt 2 闸关)。 + +#### 7.10.14 B6——dig_combo 死读数删除 + +**定值**:本批删除,范围=死读数+combo 加成分支+`combo_cap` 参数管线一个整体(`battle_orchestrator.gd:635-647` 读数与分支、grant_segment.gd `:54/:61/:62` 收集与实参、`_feat_yield_adjust` 第五参)。实证:全仓无任何数据行声明 `dig_combo`(feats.tres/treasure_items.tres/树合成行三源零命中);`combo_cap>0` 需 yield_mult 行声明 cap>0——feats.tres 唯一 `"cap"` 行属石肤 ac_bonus(`:576-583`),yield_mult 带 cap 行零个 ⇒ `combo_val` 恒 0 且 `combo_cap` 恒 ≤0,分支恒短路,**删除零行为差**(同种子复放/V25/全部回归零影响)。删除依据:该位点(`_feat_yield_adjust` 读数行)本批必触(counter 签名改 ctx),迁移一个已证死路与重构立意相悖;`settle_segments_test.gd:32-33` 以 dig_combo 为样本 id 同批换活 id。**原文「需你一句确认」按约束推导闭合为定值,可否决——否决的代价=死路代码以新签名迁入新机制。** + +#### 7.10.15 B4——旧档验收补条 + +**定值**:§4.1 增 **H1(旧档断点加载不崩)**:旧断点 `adventure_counters` 含旧键(`tree_sense_sharp_used`=2 等)→ `resume_adventure` 受理零崩溃、旧键留桶成死键(无迁移——2026-10-18 代码术语刷新批先例)。载体=`feat_vouchers_test.gd` V16 旧档同构先例(`:124-127` bp_legacy 注入旧键续玩受理)。 + +#### 7.10.16 B1/B2/B3/B5——登记与归属 + +- **B1**:新增 06 条目「效果引擎系统无状态原则缺架构文档条目」(文档轨·待文档设计)——后续文档批补 architecture.md「架构原则」条目;实现批报告仍作反哺点。§10.3 所引 `design/registry/` 两 yaml 已随 2026-10-19 用户裁注销删除,该节对 yaml 的引用失义、以本条与 §7.9 #1 为准。 +- **B2**:06「计数器寿命域未统一」条目本轮改写(现状换代=无状态化重构方向、状态推进「文档设计已闭合+待写卡」)——后人从 06 进入即见新方向。 +- **B3**:天赋树锋/守重新定价=独立议题,不登记不进批(现值非缺陷非待办;若日后提起再立条目)。 +- **B5**:roadmap 当前位 stale 已呈报在案,归并行会话,不动。 + +--- + ## 8. 已作废的旧方向(防重走) 2026-10-19 前半场提出的「**寿命域统一口径**」方案(五档/四档/两档枚举、`domain` 键扩词表、`reset_at` 退役、D1–D9 裁决单)**整体作废**。作废理由:该方案的隐含前提是「引擎持有状态、需要一个字段说明它活多久」;改为分桶后,**寿命由宿主对象天然决定,不需要寿命字段**。 From f2bb58717033ef78ea6a413123ff4022366cf40b Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 07:19:29 +0800 Subject: [PATCH 09/59] =?UTF-8?q?docs(=E6=95=88=E6=9E=9C=E5=BC=95=E6=93=8E?= =?UTF-8?q?=E6=97=A0=E7=8A=B6=E6=80=81=E5=8C=96=C2=B7=E5=86=99=E5=8D=A1):?= =?UTF-8?q?=20=E9=9C=80=E6=B1=82=E5=8D=A1=E7=89=87=E6=88=90=E6=96=87?= =?UTF-8?q?=EF=BC=88reports/=E9=9C=80=E6=B1=82=E5=8D=A1=E7=89=87-=E6=95=88?= =?UTF-8?q?=E6=9E=9C=E5=BC=95=E6=93=8E=E6=97=A0=E7=8A=B6=E6=80=81=E5=8C=96?= =?UTF-8?q?=E6=89=B9-2026-10-20.md=EF=BC=8C=E9=9B=B6=E5=BE=85=E8=A3=81?= =?UTF-8?q?=E7=82=B9=E5=BC=80=E5=B7=A5=E9=97=A8=3DU0=EF=BC=89=E2=80=94?= =?UTF-8?q?=E2=80=94T0=E2=80=93T8=20=E4=B9=9D=E5=8D=A1=E5=B8=A6=E7=AD=BE?= =?UTF-8?q?=E5=90=8D/=E6=96=AD=E8=A8=80/=E8=90=BD=E7=82=B9=E3=80=81?= =?UTF-8?q?=E9=AA=8C=E6=94=B6=20V1=E2=80=93V14=20=E4=B8=89=E9=97=AE?= =?UTF-8?q?=E9=80=90=E6=9D=A1=E5=8F=AF=E7=AD=94=E3=80=81=E5=8F=98=E5=BC=82?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E4=BA=94=E6=9D=A1=E3=80=81V12=20=E5=85=B7?= =?UTF-8?q?=E5=90=8D=E9=94=9A=EF=BC=8B=E9=94=9A=E6=96=B0=E9=B2=9C=E5=BA=A6?= =?UTF-8?q?=E6=A0=B8=E5=AF=B9=E6=AD=A5=EF=BC=9B06=20=E6=9D=A1=E7=9B=AE?= =?UTF-8?q?=E6=8E=A8=E8=BF=9B=E3=80=8C=E5=B7=B2=E5=86=99=E5=8D=A1=EF=BC=88?= =?UTF-8?q?=E6=9C=AC=E5=8D=A1=E8=B7=AF=E5=BE=84=EF=BC=89=E3=80=8D=EF=BC=9B?= =?UTF-8?q?=E6=8F=90=E6=A1=88=20=C2=A710.1=20=E8=A1=A5=E8=A1=8C=E5=8F=B7?= =?UTF-8?q?=E5=86=8D=E6=BC=82=E7=A7=BB=E6=B3=A8=E8=AE=B0=EF=BC=88c5200b6b?= =?UTF-8?q?=20=E6=B3=A8=E9=87=8A=E6=B8=85=E5=81=BF=E5=90=8E=E4=BB=A5?= =?UTF-8?q?=E5=8D=A1=E7=89=87=E5=BC=80=E5=B7=A5=E5=89=8D=E5=AE=9E=E6=9F=A5?= =?UTF-8?q?=E4=B8=BA=E5=87=86=EF=BC=89=EF=BC=9B=E5=8D=A1=E7=89=87=E7=BB=8F?= =?UTF-8?q?=E7=8B=AC=E7=AB=8B=E4=BC=9A=E8=AF=9D=E5=AF=B9=E6=8A=97=E5=A4=8D?= =?UTF-8?q?=E6=A0=B8=E4=BA=94=E9=A1=B9=E5=9B=9E=E7=82=89=E5=85=A8=E8=90=BD?= =?UTF-8?q?=EF=BC=88=E8=A1=8C=E5=8F=B7=E7=BE=A4=E8=AE=A2=E6=AD=A3/V9=20ass?= =?UTF-8?q?ert=20=E4=BE=A7=E9=97=AD=E7=8E=AF/=E5=88=A4=E5=AE=9A=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=90=8D=E8=90=BD=E5=AE=9A/=E4=BC=B0=E6=97=B6?= =?UTF-8?q?=E5=AF=B9=E9=BD=90/=E8=A3=B8=E5=BC=95=E6=93=8E=E6=AE=B5?= =?UTF-8?q?=E5=AE=9E=E6=95=B0=2053=20=E5=A4=84=EF=BC=89=E2=80=94=E2=80=94-?= =?UTF-8?q?-docs=20=E9=97=B8=E5=85=A8=E7=BB=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/gdd/06-待办清单.md | 2 +- .../提案-效果引擎无状态化-2026-10-19.md | 2 + .../需求卡片-效果引擎无状态化批-2026-10-20.md | 292 ++++++++++++++++++ 3 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 reports/需求卡片-效果引擎无状态化批-2026-10-20.md diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index bbf26225..b95a4991 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -636,7 +636,7 @@ **归属**:architecture.md 与 game/core/effect_engine.gd(待立独立批) -**状态**:待裁决(是否统一寿命域口径——2026-10-19 已裁:统一口径方案作废,改走无状态化重构)+文档设计已闭合(design/research/提案-效果引擎无状态化-2026-10-19.md v1.2——2026-10-20 §7.10 闭合)+待写卡 +**状态**:待裁决(是否统一寿命域口径——2026-10-19 已裁:统一口径方案作废,改走无状态化重构)+文档设计已闭合(design/research/提案-效果引擎无状态化-2026-10-19.md v1.2——2026-10-20 §7.10 闭合)+待写卡+已写卡(reports/需求卡片-效果引擎无状态化批-2026-10-20.md) --- diff --git a/design/research/提案-效果引擎无状态化-2026-10-19.md b/design/research/提案-效果引擎无状态化-2026-10-19.md index 63508a4d..665dc416 100644 --- a/design/research/提案-效果引擎无状态化-2026-10-19.md +++ b/design/research/提案-效果引擎无状态化-2026-10-19.md @@ -550,6 +550,8 @@ func counters_merge_export(exported): ### 10.1 行号订正汇总 +> 🔴 **2026-10-20 再漂移注记**:本表「实际」列的行号以提案复核时点为准;其后的 `c5200b6b`(禁写变更记录批·代码注释清偿)已使本文件部分行号再度漂移(如引擎成员块现役 :83-88、`counters_seed` :255、`EffectEngine.new` :271、树合成行 :136-155)。行号时效以需求卡片 `reports/需求卡片-效果引擎无状态化批-2026-10-20.md`(开工前实查)为准,本节数字仅作沿革参考。 + | 草案初版写法 | 实际 | 说明 | |---|---|---| | `effect_engine.gd` :83/84/85/86/88 | :86/87/88/89/91 | 整体 +3——迭代 31 卡② 在 `:42-44` 插入 `forgive_seal_miss` 三行注释 | diff --git a/reports/需求卡片-效果引擎无状态化批-2026-10-20.md b/reports/需求卡片-效果引擎无状态化批-2026-10-20.md new file mode 100644 index 00000000..e7099b8a --- /dev/null +++ b/reports/需求卡片-效果引擎无状态化批-2026-10-20.md @@ -0,0 +1,292 @@ +# 需求卡片:效果引擎无状态化批(计数器外置·分桶) + +- **日期**:2026-10-20 +- **来源**:06-待办清单「计数器寿命域未统一」条目(2026-10-18 登记,来源=会话提及,设计面=文档轨),设计已闭合推进至待写卡(唯一事实源:`design/research/提案-效果引擎无状态化-2026-10-19.md` v1.2——§3 目标形态、§7 N1–N6 定值、§7.7 采集定值、§7.10 缺口闭合定值) +- **批性质**:工程直入类·架构重构(restructure)——代码域批,禁写 `design/` 整个目录与根规则文件,产出物只落 `reports/` +- **估时**:≈3.75–5.75d(T0–T8 单卡;超盒切分预案=T7 拆「断言新增/迁移」与「复放比对」两波先后挂,T3 与 T7 测试迁移互不阻塞可并行切) +- **状态**:成文待审——零待裁点,开工门=U0(用户发令) + +--- + +## 1. 目标与完成定义 + +把 `EffectEngine` 从「解释器+自带状态计数器容器」改为**纯计算引擎(零运行时状态)**:效果侧计数器按 round/battle/level/adventure 四只桶外置、由各生命周期的宿主对象持有(寿命随宿主生灭,不需要寿命字段),事件触发时经 ctx 参数传入,引擎只做判定;计数器归属用 id 前缀表达并加载期强校验。 + +**完成定义**(全部满足才算完): + +1. `EffectEngine` 实例内无任何运行时可变数据(仅剩编译产物 `_triggers` 与只读依赖 `db`); +2. 计数器四桶外置:round/battle 桶挂 `BattleOrchestrator`、level 桶挂 `LevelRunner`、adventure 桶挂 `run_ledger.adventure_counters`,桶随宿主生灭; +3. 搬运链整段删除:`counters_export`/`counters_seed`(引擎)与 `counters_seed_snapshot`/`counters_merge_export`(RunLedger)零残留; +4. `adventure_runner.gd:838-841` 硬编码清除名单(`_reset_tree_limited_counters`)删除,按关清零由 LevelRunner 每关 new 天然承载; +5. 计数器归属机器可读且加载期可校验:`.tres` 行(errs→加载致命)与树合成行(`_push_trigger` assert)双落点,写错前缀即致命; +6. 同种子复放比对按分组判读通过(V12):未受影响局 RUNSUM 全字段逐位一致;受影响局输入面字段恒等+`levels_cleared` 分布不得上行——**不声称零漂移**(adventure 桶跨战持久与天赋树每关限次是已定性预期差异,提案 §7.7/§7.8); +7. `dig_combo` 死读数连同 combo 分支删除,零行为差(§7.10.14); +8. 旧档断点含旧计数键加载不崩(V13,无迁移——2026-10-18 代码术语刷新批先例)。 + +## 2. 设计事实源 + +`design/research/提案-效果引擎无状态化-2026-10-19.md` **v1.2**(2026-10-20 设计闭合版)——本卡全部设计定值的唯一出处: + +- 目标形态与四桶表=提案 §3(3.1 宿主定值/3.2 接口定稿/3.3 前缀归属); +- N1–N6 定值=提案 §7;不发起全冒险模拟采集=提案 §7.7(零数值改动=零采集,本批一个数值表值都不改);搬运链缺陷全解=提案 §7.8; +- 写卡前缺口闭合定值=提案 §7.10(ctx 结构/容器类型与测试接口/前缀校验双落点/写口静态化/施加面补列/改名传播面/保险双账不改面/A1 注入口径/level 桶接口/复放分组判读/mine_hit 构造/dig_combo 删除/H1 补条)。 + +与 06 条目状态里的闭合凭据一致(v1.2)。 + +## 3. 现状事实(2026-10-20 代码级实查,开工自行复核) + +**引擎侧**: + +- `game/core/effect_engine.gd:83-88` 五成员:`_triggers`(:83,编译产物,留)、`_counters`(:84,运行时容器,搬走)、`_reset_on_round_start`(:85)/`_adventure_counter_ids`(:86-87 含续行,编译名单,随分桶删除)、`db`(:88,只读,留)。 +- 接口与调用点:`rebuild()` :98;`dispatch()` :208(调用点 6 处——`battle_orchestrator.gd:91` `_fx_emit` 汇聚面/`damage_controller.gd:78` `_fx_hits` 汇聚面/`action_economy.gd:103/:164/:191`/`reward_economy.gd:65`);`counter()` :224(外部读 4 处:`battle_orchestrator.gd:638`、`damage_controller.gd:345`、`grant_segment.gd:103/:205`);`counter_add()` :228(写 6 面:`action_economy.gd:108/:111/:169`、`damage_controller.gd:351/:464`、`grant_segment.gd:327`);`counter_spend()` :237(`battle_orchestrator.gd:714` 受理闸);`counters_export()`/`counters_seed()` :246/:255;`validate_trigger_row()` :351(静态,`data/schemas/feat_table.gd:44`、`treasure_item_table.gd:104` 消费)。 +- round_start 清零在 `dispatch` 特判内(:210-212 按名单清零);真实发射点=`battle_orchestrator.gd:97 _emit_round_start()`(调用点 `:425` 首轮/`:1077` 续轮)。 +- `DO_KEYS` :72-75 含 `domain`/`reset_at` 两键;树合成行 `:136-155` 硬编码 `tree_sense_sharp_used`/`tree_sense_guard_used`(走 `_push_trigger`,现仅 assert 事件域——前缀零校验)。 + +**搬运链与自锁**:`run_ledger.gd:40-45` `counters_merge_export` 判空早退(:42)⇒ 全新开局 adventure 域四枚整局不写入(断点回填 :206-208 是唯一解锁路径);战末导出在 `battle_orchestrator.gd:1122-1123`,战首回灌 `:390`。 + +**宿主侧**:`battle_orchestrator.gd:271` `_fx = EffectEngine.new`(_init :268-292 段内 `set_fx` 三处注入 :280-282);`begin_battle` :372-373 `_ledger = enc["ledger"]` 或缺省新账;`level_runner.gd:450-482` `_start_battle` 每战 new 编排器、enc 装配(:471 `"ledger"` 下传行);`adventure_runner.gd:843-845` 每关 new LevelRunner+调 `_reset_tree_limited_counters`;`:255` 新冒险置空 `run_ledger.adventure_counters = {}`;断点写键 `:1033`/回填 `:206-208`。 + +**保险双账**:`grant_segment.gd:311-317` 同一标错分支内 `_perfect_forgiven` 加一(:314)与 `_apply_counter_hit` 落 `insurance_used`(:315→:327)**同点双记各司其职**——前者供判定段两账相减、后者供 when `lt 1` 限次闸;本批不改面(V25 迁移保绿即证)。 + +**死路**:`battle_orchestrator.gd:635-647` `_feat_yield_adjust` 读 `dig_combo`(全仓无数据行声明——feats.tres/treasure_items.tres/树合成行三源零命中;feats.tres 唯一 `"cap"` 行属石肤 ac_bonus `:576-583`,yield_mult 带 cap 行零个)⇒ `combo_val` 恒 0、`combo_cap` 恒 ≤0,分支恒短路。 + +**数据行**:`feats.tres` 计数 id 共 14 枚+树合成 2 枚=16 枚;`reset_at: round_start` 恰 4 行(`round_blast_spent` :212/`instinct_atk` :494/`round_mines` :518/`round_digs` :723——全带 round_ 前缀或随改名获得前缀,分桶后「整桶清空」与现役名单清零逐键等价);`domain` 键行:`twin_digs` :31/`pain_layers` :377/:535/:628(另 :407 附近 set 行)/`insurance_used` :877(battle)。 + +**测试面**:`tests/run_all.gd` manifest(负面套件协议 `expect:1`+`negative:true`,先例 `reward_dangling_treasure_test.gd` 夹具注入);`tests/README.md:58` 记套件数 26;`game/presentation/` 全目录 counter_id 与 16 枚 id 字面零命中(呈现层不入改名传播)。 + +## 4. 设计契约(违反即返工;🔴 触碰=L3 停机呈报) + +1. 🔴 **确定性**:除 V12 已定性的两处行为变更(adventure 桶真跨战持久、天赋树锋/守真每关限 2)外,同种子复放必须逐位一致——读写时序、装载序、命中序零变化;命中序=装载声明序写死不碰。 +2. 🔴 **数值零改动**:本批不改任何数值表值;天赋树锋/守「每战 2→每关 2」是回到设计意图(`effect_engine.gd:137` 注释),不是平衡调整;禁顺手调任何 provisional 值。 +3. 🔴 **round 桶就地清空**:轮始清零必须 `.clear()`(或等效就地清空),**禁 `= {}` 重赋值**——重赋值会切断 ctx 持有的引用。 +4. 🔴 **搬运链删除后禁留任何副本同步时点**:战末导出/战首回灌/判空守卫三类代码不得以任何形态复活(含「防御性保留」)。 +5. 🔴 **保险双账不改面**:`_perfect_forgiven` 与 `insurance_used` 同点双记关系原样保持(§3 现状事实),禁合并、禁迁账、禁改判定段两账相减语义(N6 定值)。 +6. 🔴 **两落点同源**:前缀校验的判定函数唯一(静态单点),`validate_trigger_row` 与 `_push_trigger` 共用;禁两处各写一份前缀表。 +7. 🔴 **容器与接口逐字锁定**:`EffectContext` 四字段名 `round_bucket`/`battle_bucket`/`level_bucket`/`adventure_bucket`;编排器成员 `fx_counters_round`/`fx_counters_battle`/`counters_ctx`;LevelRunner 成员 `level_counters`;enc 下传键 `"level_counters"`;改名 4 枚新 id `adv_twin_digs`/`lvl_tree_sense_sharp_used`/`lvl_tree_sense_guard_used`/`round_instinct_atk`。实现期不得另起名。 +8. 🔴 **pain_layers 归 battle 零语义变更**:只改归属(删 `domain` 键),「攒层→下次攻击附加→用后清零」行为逐位不变(N4)。 +9. 🔴 **旧档不迁移**:改名后旧档断点旧键成死键属预期(H1 只断言不崩);禁加迁移体、禁动 `SAVE_FORMAT_VERSION`。 +10. 🔴 **实现批禁写 `design/` 与根规则文件**;`sim-data/` 零采集零重跑(§7.7 定值——本批零数值改动,锚与读数不动)。 +11. 🔴 **同名成员禁遮蔽内建**:ctx 字段名已避讳(`round_bucket` 非 `round`),实现期引入新成员时同规。 + +## 5. 范围边界 + +**做**:§1 完成定义 1–8 全部;`EffectContext` 新类;引擎接口 ctx 化与写口静态化;7 个施加点迁移;前缀校验双落点;4 枚 id 改名+`domain`/`reset_at` 键删除;`dig_combo` 死路删除;测试新增/迁移/变异验证;同种子复放比对(零局新采集,锚内子集 20 种子);`static_scan.sh` 新增 S 段+`run_all.gd` manifest 登记。 + +**不做**(去向已定): + +| 不做项 | 去向 | +|---|---| +| `charge_reset`(秘宝充能周期)、凭证件裸标量、SaveManager meta 域 | 提案 §9 已排除,不动 | +| 断点快照结构(level 桶不进断点——N3:写入时刻恒空,「进」是空操作) | 不动;「退菜单续玩可刷新每关限次」属既有行为,登记真人检测面(V14 目检项) | +| 编排器 5 个效果运行态(`_fx_ac_round`/`_fx_ac_battle`/`_fx_new_resource_types`/`_fx_bonus_delta`/`_perfect_forgiven`) | N6 定值:只归计数器,留编排器 | +| 天赋树锋/守重新定价 | 独立议题,不进本批(§4.5 B3) | +| architecture.md「系统无状态」原则补条 | 已登记 06 新条目(文档轨·待文档设计),归文档批;本批反哺点带依据 | +| `roadmap.md` 当前位 stale | 已呈报在案,归并行会话 | +| MC 采集(任何档位) | §7.7 定值:零数值改动=零采集 | +| 元素类型精化(`Dictionary[String, int]`) | S9 现行口径 `Dictionary[Variant, Variant]` 合格,精化另走裁决 | + +## 6. 关联文档同步面(实现批禁写本表所列文档——义务全部走 `reports/iter-反哺点-<日期>.md`) + +| 文档 | 关联点(本批实现改变它的哪条陈述) | 同步义务 | +|---|---|---| +| `design/engineering/architecture/architecture.md` | ①模块归属表 effect_engine 行「对外暴露」列记 `counters_export·counters_seed` 与「domain=adventure 跨战斗持久」(:116)——改后均不存在;②战斗域装配现状节「战末 export/开局 seed 时点语义不变」(:125)随搬运链删除失义;③「架构原则」节缺「系统无状态」条目(立项判据补条) | 反哺点清单逐条列出(①②改写成 ctx 形态描述、③指向 06 在册条目「效果引擎系统无状态原则缺架构文档条目」),用户裁决后归文档批 | +| `game/tests/README.md` | :58 记「manifest 已登记实跑 26 套件」——本批新增 1 负面套件 | 反哺点(机械面文档,批后由文档批更新套件数与段描述) | +| `design/gdd/06-待办清单.md` | 上游条目「计数器寿命域未统一」随批完成整条删除(收口=batch-closure 技能);条目现状内引用的行号(:838-841 等)随实现漂移 | 批内不动;收口时整条删除(行号订正随之消亡) | +| `design/gdd/07-体验验证清单.md` | 天赋树锋/守第二次后无减免=玩家可感知削弱,需真人目检入册 | 反哺点(登记项见 §9 真人目检面) | +| `design/gdd/术语表.md` | 零关联(本批不造新术语;四桶/前缀均为代码标识符非玩家术语) | 无 | + +## 7. 卡前文件结构图 + +**新建**: + +| 文件 | 职责 | +|---|---| +| `game/core/effect_context.gd` | `EffectContext`——四桶引用束(RefCounted,四公开类型化字段,零方法) | +| `game/tests/unit/data_config/counter_prefix_fatal_test.gd` | E1 负面套件:坏前缀 counter_id 行 → load_tables 拒绝(expect 1) | + +**修改**: + +| 文件 | 改动 | +|---|---| +| `game/core/effect_engine.gd` | 删三状态成员与搬运接口;dispatch/counter 带 ctx;写口改静态纯函数+`bucket_of`;`_push_trigger` 前缀校验;DO_KEYS 删两键;合成行(:136-155)id 改名 | +| `game/core/battle_orchestrator.gd` | 两桶公开成员+ctx 构造挂载;set_fx 扩参;`dig_combo` 死路删除;战末导出两行删除 | +| `game/core/action_economy.gd` | set_fx 扩参;3 dispatch 面+3 写口静态化 | +| `game/core/damage_controller.gd` | set_fx 扩参;dispatch 汇聚面+1 读 2 写静态化 | +| `game/core/reward_economy.gd` | set_fx 扩参;dispatch 面加 ctx | +| `game/core/settlement/grant_segment.gd` | `_apply_counter_hit` 静态化;2 读口 ctx 化;`combo_cap` 收集与实参删除 | +| `game/core/run_ledger.gd` | 删 `counters_seed_snapshot`/`counters_merge_export` | +| `game/core/adventure_runner.gd` | 删 `_reset_tree_limited_counters` 及调用点 | +| `game/core/level_runner.gd` | `level_counters` 公开成员+enc `"level_counters"` 下传 | +| `game/data/tables/feats.tres` | 4 枚 id 改名;`domain`/`reset_at` 键逐行删除 | +| `game/tests/static_scan.sh` | 新增 S 段:旧件符号+带引号旧 id 字面零命中 | +| `game/tests/run_all.gd` | manifest 登记负面套件 | +| `game/tests/unit/core/effect_words_t1_test.gd` | ⑥ export/seed 块、⑦ reset_at/spend 块重写为桶语义;裸 dispatch/写口 ctx 化 | +| `game/tests/unit/core/tree_rules_v11_test.gd` | :29-39 合成行字面 id 随改名 | +| `game/tests/unit/core/feat_vouchers_test.gd` | V16 键名随前缀;V25 迁移保绿;新增 H1 旧档不崩断言 | +| `game/tests/unit/core/settle_segments_test.gd` | `:32-33` 样本 id 换活 id+ctx 形态 | +| `game/tests/unit/core/treasure_effects_test.gd` | 裸 dispatch 面 ctx 化(:34/:45/:53-56) | +| `game/smoke/smoke_all.gd` | 新增 V1–V6/V8/V12 冒烟断言段;`:6076-6083`/`:6124-6128` 旧链删除;`:1419-1602` 裸引擎段 53 处 dispatch+8 处写口改 ctx 形态;各 rig enc `"adventure_counters"` 死键清除;`:1610` rebuild 调用零迁移 | + +## 8. 任务卡 T0–T8 + +### T0 基线(0.25d) + +- [ ] worktree/分支开工(process-conventions §1);拷主区 `.godot/` 与字体 `.import` 边车 +- [ ] 基线三查记档:冒烟全绿数目、单元 26 套件全绿、探针基线;记录 `sim-data/` 现行锚文件名与 sha1(**只记录不跑**——零数值改动禁采集) +- [ ] `git log --oneline -1` 与 `tools/run_all_gates.sh --code` 基线档记档(起点绿态) + +**产出**:基线档(实现报告 T0 节)。 + +### T1 `EffectContext` 新建+四宿主接线(0.5–1d) + +**取用**:无。**产出**:`EffectContext`(字段名见契约 7)——T2–T7 全部引用。 + +- [ ] 新建 `game/core/effect_context.gd`:`class_name EffectContext extends RefCounted`;四字段 `var round_bucket: Dictionary[Variant, Variant] = {}`(battle_bucket/level_bucket/adventure_bucket 同型);文件头注 ≤8 行两类白名单;跑一次编辑器扫描刷新全局类缓存(code-conventions §4.5) +- [ ] `BattleOrchestrator` 增三公开成员:`fx_counters_round`/`fx_counters_battle`(`Dictionary[Variant, Variant]`)+`counters_ctx: EffectContext`;`_init` 内构造 ctx 并挂自有两桶引用 +- [ ] `LevelRunner` 增公开成员 `level_counters: Dictionary[Variant, Variant]`;`_start_battle` enc 增 `"level_counters": level_counters`(`"ledger"` 行 :471 后) +- [ ] `begin_battle` :373 后挂载:`counters_ctx.adventure_bucket = _ledger.adventure_counters`;`enc.get("level_counters")` 为 Dictionary 时 `counters_ctx.level_bucket = enc["level_counters"]`(缺省=调试/单场空桶,与 `_ledger` 缺省新账同式) +- [ ] `set_fx` 三处扩参:`func set_fx(fx: EffectEngine, ctx: EffectContext) -> void`(action_economy.gd:48/damage_controller.gd:70/reward_economy.gd:23),三协同件各增 `_ctx` 成员;`battle_orchestrator.gd:280-282` 调用点同步 +- [ ] 删 `adventure_runner.gd:838-841` `_reset_tree_limited_counters` 与 `:845` 调用点(同批摘除冒烟 `:6125` 直呼——F2 面随 T7 断言同轮) +- [ ] 孤立验证:`--headless --script` 最小驱动 `EffectContext.new()`+编排器 `_init` 构造 ctx 成功(新码先行孤立验证纪律) + +### T2 引擎删状态+ctx 接口+静态写口(0.5–1d) + +**取用**:T1 的 `EffectContext`。**产出**:引擎新接口面——`dispatch(ctx, event, payload, facts)`/`counter(ctx, id)`/`static bucket_of(ctx, id)`/`static counter_add(ctx, id, value, set_mode=false)`/`static counter_spend(ctx, id, value) -> bool`。 + +- [ ] 删成员 `_counters`/`_reset_on_round_start`/`_adventure_counter_ids`(:84-87 含续行)与 rebuild 内三处清零/收集(:100-101/:156-157/:181-190) +- [ ] `rebuild()` 签名不变(`feat_ids, item_ids, tree_rules`)——冒烟 `:1610` 调用面零迁移 +- [ ] `dispatch(ctx: EffectContext, event: String, payload: Dictionary, facts: Callable = Callable()) -> Array`;round_start 特判(:210-212)改 `ctx.round_bucket.clear()`——**就地清空**(契约 3) +- [ ] `counter(ctx: EffectContext, counter_id: String) -> int`(读 `bucket_of(ctx, counter_id)`) +- [ ] 新增 `static func bucket_of(ctx: EffectContext, counter_id: String) -> Dictionary[Variant, Variant]`:`round_`→round_bucket/`lvl_`→level_bucket/`adv_`→adventure_bucket/其余→battle_bucket(前缀规则唯一出处) +- [ ] 新增静态 `counter_add`/`counter_spend`(签名见产出块;算术与阈值闸语义从现役 :228-242 逐字保留);删实例版两方法与 `counters_export`/`counters_seed`(:246-257) +- [ ] `run_ledger.gd` 删 `counters_seed_snapshot`(:36-37)与 `counters_merge_export`(:40-45) +- [ ] `DO_KEYS` 删 `"domain"`/`"reset_at"`(:72-75) +- [ ] 孤立验证:裸引擎 rig `EffectEngine.new(null)`+自建 ctx,合成一行 counter_add 行 dispatch→静态写口→counter 读回一致 + +### T3 施加点改写+dig_combo 死路删除(0.5–1d) + +**取用**:T2 全部接口。**产出**:生产侧零 `_fx.counter_add(`/`_fx.counter_spend(`/`counters_export` 残留(V10 静态扫描可证)。 + +- [ ] `action_economy.gd`::103/:164/:191 dispatch 加 `_ctx`;:108/:111/:169 写口改 `EffectEngine.counter_add(_ctx, ...)`——:103-108「counter_spend 订阅→加收对价+积计数」读-判-写序列逐字保留(§7.10.6) +- [ ] `damage_controller.gd`::78 dispatch 加 ctx;:345 读改 `EffectEngine.counter(_ctx, ...)`;:351/:464 写口静态化 +- [ ] `reward_economy.gd`::65 dispatch 加 ctx +- [ ] `grant_segment.gd`::103/:205 读口 ctx 化(经 `oc.counters_ctx`);:327 `_apply_counter_hit` 内写口改静态(调用点 :66/:122/:156/:215/:264 零改动);:54/:61/:62 `combo_cap` 收集与实参删除 +- [ ] `battle_orchestrator.gd`::88 `_fx_emit` 加 `counters_ctx`;:714 受理闸改 `EffectEngine.counter_spend(counters_ctx, ...)`;:635-647 删 `dig_combo` 死读数+combo 加成分支+`_feat_yield_adjust` 第五参(§7.10.14,零行为差);:1122-1123 战末导出两行删除(:1118-1121 bonus_delta 汇入保留——那是 N6 留编排器的运行态,不是计数器) +- [ ] 孤立验证:单场编排 rig begin_battle→request_dig 一次→`run_ledger.adventure_counters` 立即可见写入(无战末时点依赖) + +### T4 round 泛化+宿主清零确认(0.25d) + +**取用**:T2 的 round_start 特判、T1 的宿主成员。**产出**:三清零点在位(轮始一处+宿主 new 两处)。 + +- [ ] 确认轮始清零唯一入口=引擎 dispatch 特判(T2 已改);编排器侧零新增清零代码 +- [ ] 确认 battle/level 桶零显式清零代码(宿主 new 天然空);全仓 grep `_reset_on_round_start`/`_adventure_counter_ids`/`_reset_tree_limited_counters` 零命中 +- [ ] 孤立验证:round 桶写非零→dispatch("round_start")→整桶空;battle 前缀键同一 dispatch 下不动 + +### T5 前缀校验双落点(0.25d) + +**取用**:T2 的 `bucket_of` 前缀规则。**产出**:加载期前缀致命通道(V9)。 + +- [ ] 新增静态判定函数 `static func counter_id_legal(counter_id: String) -> bool`(名字锁定):无前缀=true(battle);`round_`/`lvl_`/`adv_` 前缀=true;其余带前缀形态(`meta_` 等)=false——前缀规则与 `bucket_of` 同源(bucket_of 解析为 battle 而 id 首段含 `_` 即非法,单一规则表) +- [ ] `validate_trigger_row` 增分支:`do` 含 `counter_id` 时校验,非法→errs 追加 `{"category": "enum", ...}` 违例 +- [ ] `_push_trigger` 增 assert:`do` 含 `counter_id` 时同规则 assert(树合成行路径,写错调试期致命;assert 消息以 `[效果引擎]` 前缀起头,供孤立验证扫描) +- [ ] 孤立验证(V9 assert 侧):`--headless --script` 最小驱动 rebuild 带「counter_id 带非法前缀」的合成行——输出扫到 `[效果引擎]` assert 签名=拦截在位(debug 通道;assert 不改退出码,判据=输出签名扫描) +- [ ] 新建 `game/tests/unit/data_config/counter_prefix_fatal_test.gd`:copy_tables 夹具→向 feats.tres 注入 `"counter_id": "meta_probe"` 行→`load_tables` 必须拒绝→quit(1);违规放行 quit(2)(reward_dangling_treasure_test.gd 同构,退出码协议同款) +- [ ] `tests/run_all.gd` manifest 登记:`{"path": "res://tests/unit/data_config/counter_prefix_fatal_test.gd", "expect": 1, "negative": true}` + +### T6 数据行与合成行改名(0.25d) + +**取用**:契约 7 的 4 枚新 id。**产出**:16 枚 id 全部合规(前缀即归属)。 + +- [ ] `feats.tres`:`"twin_digs"`→`"adv_twin_digs"`(:29);`"instinct_atk"`→`"round_instinct_atk"`(:492);`pain_layers` 各行删 `"domain": "adventure"` 键(:375-377/:407 邻近/:533-535/:626-628——归 battle,N4);`twin_digs` 行删 domain 键、`insurance_used` 行删 `domain: battle` 键(:875-877);全部 `reset_at` 键删除(:209-212/:490-494/:514-518/:719-723) +- [ ] `effect_engine.gd` 合成行(:136-155):`tree_sense_sharp_used`→`lvl_tree_sense_sharp_used`、`tree_sense_guard_used`→`lvl_tree_sense_guard_used`(when id 与 counter_id 共六处字面:锋/守各 when 两行+do counter_id 一行);:116-122 注释内「domain=adventure」叙述同步改前缀口径 +- [ ] 全仓 grep 确认零 `domain`/`reset_at` 键残留于 feats.tres;`pain_layers`/`geo_types` 等 12 枚无前缀 id 零改名(无前缀=battle 即归属) + +### T7 验收断言+旧测试迁移+变异验证+同种子复放比对(1–1.5d) + +**取用**:T1–T6 全部产物;§9 验证闸清单(V1–V14 断言内容以本卡为唯一规格)。**产出**:V1–V13 全绿+变异验证记录表+G1 判读记录。 + +- [ ] **新增单测断言**(套件内新增,断言尾缀〔无状态化 Vn〕):V2/V3/V7/V13 落 `feat_vouchers_test.gd`(V16 键名 `pain_layers:3, twin_digs:5`→`adv_twin_digs:5` 等活键改写;V25 全组保绿不改断言内容;新增 H1:bp_legacy 注入 `"tree_sense_sharp_used": 2` 旧键 resume 受理零崩溃);V9 落 `counter_prefix_fatal_test.gd`(T5) +- [ ] **新增冒烟断言段**(`smoke_all.gd` 树规则段近旁):V1(两编排器共享 RunLedger,第 1 战 `request_dig(0, false)` 一次无返还+桶值 1,第 2 战一次返还成立+桶值 2);V4/V5(两编排器经 enc["level_counters"] 共享同字典:第 1 战两次 `_fx.dispatch(counters_ctx, "mine_hit", {})` 命中桶值 2,第 2 战同 dispatch 返回空且桶值不动;新 LevelRunner 新桶为空);V6(第 1 战经 `_judge_seal` 置 `insurance_used=1`,第 2 战读 0);V8(round 桶直写非零→`orch._emit_round_start()`→全零,battle 前缀键不动) +- [ ] **旧断言迁移/摘除**(F2——同批同轮):`effect_words_t1_test.gd` ⑥(:77-94 export/seed 往返)改桶语义断言(共享 adventure 桶字典往返)、⑦(:96-124 reset_at/spend)重写(round 桶轮始清空语义+静态 spend);`smoke_all.gd` `:6076-6083`(counter_add+export/seed 链)改共享桶形态、`:6124-6128`(`_reset_tree_limited_counters` 直呼)删除;`:1419-1602` 裸引擎段 53 处 dispatch+8 处写口改 ctx 形态(逐行扫尽,rig 顶自建 ctx 或取 `orch.counters_ctx`);`tree_rules_v11_test.gd:29-39` 字面随 T6 新 id;`settle_segments_test.gd:32-33` 样本 id `dig_combo`→`geo_types`+ctx 形态;`treasure_effects_test.gd:34/:45/:53-56` dispatch 加 ctx;各 rig enc `"adventure_counters": {}` 死键删除(编排器只读 `enc["ledger"]`,:372 实证) +- [ ] **静态扫描 S 段**(`static_scan.sh`):新增规则组——`counters_export`/`counters_seed`/`counters_merge_export`/`counters_seed_snapshot`/`_reset_tree_limited_counters` 零命中+带引号旧 id 字面 `"tree_sense_sharp_used"`/`"tree_sense_guard_used"`/`"twin_digs"`/`"instinct_atk"` 零命中(带引号匹配防新名误伤);`run_all_gates.sh` 域内已有 static_scan,无闸件清单改动 +- [ ] **变异验证**(§9 变异表 4 条逐条:注入→最窄闸见红→`git checkout -- <文件>` 还原→复跑回绿→记录) +- [ ] **同种子复放比对**(V12):先做**锚新鲜度核对**——用批前基线码(T0 记录的起点 commit)重放种子 81000–81001 两局,与现行锚 `sim-data/runsum_m3iter9exit_81000_n400_20261003.jsonl` 对应行逐位比对,一致方判锚可用(不一致=锚与 HEAD 玩法口径脱钩,L3 停机呈报,禁带病判读);核对通过后重放锚内 normal 档种子 81000–81019(20 局,零局新采集),按 §7.10.12 分组判读(未受影响局=feat_mode off 或装备集不含双管镐/sense 两组→全字段逐位一致;受影响局→输入面恒等+`levels_cleared` 分布不得上行);逐位差异明细记实现报告 +- [ ] 里程碑步出口:`tools/run_all_gates.sh --code`(代码域闸全绿);波内修复只做出红最小单元的最窄确认 + +### T8 产出物落位卡(0.25d) + +**取用**:T0–T7 全部记录。**产出**:`reports/` 三份齐+06 状态就绪。 + +- [ ] 实现报告 `reports/iter-实现报告-<日期>.md`:各 T 卡状态+变异验证记录表(注入点 file:line/跑的闸/红输出摘要/还原结论)+G1 判读记录+实机目检总清单(V14 登记) +- [ ] 代拍板追认单 `reports/iter-代拍板-<日期>.md`(§11 白名单内微决策逐条备案) +- [ ] 反哺点清单 `reports/iter-反哺点-<日期>.md`:§6 同步面五条逐条落点(architecture.md 三处改写文案与依据、tests/README 套件数、07 目检入册项) +- [ ] 轻闸全绿后合并前自查:`game/` 与 `tools/` 改动全在案、`design/` 与根规则文件零触碰(`git diff --stat` 核对) + +## 9. 验证闸(逐需求点验收清单) + +**闸口径**:批末=代码域闸全绿(冒烟+单元+探针+渲染/静态,`tools/run_all_gates.sh --code`)+同种子复放比对(V12,零局新采集)。里程碑步(波/T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试/工具先行孤立验证再并入全套。本批无数值改动,改前改后读数对比由 V12 分组判读承载。 + +**逐需求点清单**(断言尾缀〔无状态化 Vn〕;「测什么/怎么测/谁验」三问逐条可答): + +| # | 需求点 | 测什么 | 怎么测(注入粒度) | 落点 | 谁验 | +|---|---|---|---|---|---| +| V1 | adventure 桶跨战持久(`run_ledger.gd:42` 缺陷消解回归钉面) | 第 1 战写入第 2 战可读、读写走真实事件面 | 两编排器共享 `RunLedger`:第 1 战 `orch1.action_economy.request_dig(0, false)`(无返还,`adv_twin_digs`=1)→第 2 战(同 ledger)一次挖返还成立+桶值 2 | 冒烟新段 | 自动 | +| V2 | adventure 桶新冒险置空 | `start_adventure` 后桶空 | `start_adventure(301,...)` 后 `run_ledger.adventure_counters` 为空 | `feat_vouchers_test.gd` | 自动 | +| V3 | adventure 桶随断点往返 | 快照/回填逐位相等 | 写桶→`_on_level_finished`→`breakpoint_snapshot`→`resume_adventure`→逐键比对(键随新 id) | `feat_vouchers_test.gd`(V16 改写) | 自动 | +| V4 | level 桶同关跨战保持、进关清零 | 共享桶第 2 战保值;新 LevelRunner 新桶空 | 两编排器 enc["level_counters"] 同引用:第 2 战读 `lvl_tree_sense_*` 保持;再 new LevelRunner 断言 `level_counters` 空 | 冒烟新段 | 自动 | +| V5 | tree_sense 每关限 2 次(削弱正面确认) | 第 1 战用满→第 2 战 lt 2 闸关零命中 | V4 同款共享桶:第 1 战两次 dispatch mine_hit 命中(桶值 2)→第 2 战同 dispatch 返回空且桶值不动 | 冒烟新段 | 自动 | +| V6 | battle 桶随宿主销毁 | 第 2 战读 `insurance_used`==0 | 第 1 战 `_judge_seal` 置 1→新编排器 begin_battle 后读 0 | 冒烟新段 | 自动 | +| V7 | 完美保险每战限次一次(卡② V25 迁移保绿) | V25 全组断言原样绿 | 沿用 V25 注入口径零改写——双账同点双记不改面(契约 5) | `feat_vouchers_test.gd:130-188` | 自动 | +| V8 | round 桶轮始清空 | 轮始后 round 桶全零、他桶不动 | round 桶直写非零→`orch._emit_round_start()`→全零;`fx_counters_battle` 内键不动 | 冒烟新段 | 自动 | +| V9 | counter_id 非法前缀加载致命(.tres 行+树合成行双落点) | 坏前缀行 load_tables 拒绝;合成行 assert 触发有据 | 夹具注入 `"counter_id": "meta_probe"`→load_tables false→expect 1;assert 侧=T5 孤立验证(最小驱动 rebuild 坏前缀合成行,输出扫 `[效果引擎]` assert 签名)+变异表第 4 行证明拦截 | `counter_prefix_fatal_test.gd`(expect 1, negative)+T5 孤立验证 | 自动 | +| V10 | 旧件零残留 | 五符号+四带引号旧 id 字面全仓零命中 | static_scan 新 S 段(规则见 T7) | `static_scan.sh` | 自动 | +| V11 | 旧断言同批摘除 | 冒烟/单测无旧件断言残留 | V10 扫描面覆盖测试文件+F2 清单逐项核对(`effect_words_t1` ⑥⑦/`smoke :6076-6083`/`:6124-6128`/`:1419-1602`) | 冒烟+单测迁移轮 | 自动+实现报告核对表 | +| V12 | 同种子复放分组判读 | 锚新鲜度核对通过后:未受影响局逐位一致;受影响局输入面恒等+`levels_cleared` 不上行 | 批前基线码先重放 81000–81001 两局与现行锚 `runsum_m3iter9exit_81000_n400_20261003.jsonl` 逐位比对(新鲜度闸);通过后批后码重放锚内 normal 档 81000–81019(20 局);分组判读按提案 §7.10.12 | 复放脚本+实现报告判读记录 | 自动+人工判读 | +| V13 | 旧档断点加载不崩 | 旧键 resume 受理零崩溃 | bp_legacy 注入 `"tree_sense_sharp_used": 2`→`resume_adventure` 受理、旧键留桶 | `feat_vouchers_test.gd`(V16 同构) | 自动 | +| V14 | 天赋树锋/守削弱玩家可感知(登记不阻塞) | 每关第 3 次起无减免/无返还 | 用户实战目检:同关第 3 次踩雷不再减半、第 3 次标错不再返 AP | 实机目检总清单+07 入册(反哺点) | 用户目检 | + +**变异验证必做**(无变异红记录只写「已实现,拦截能力未证」): + +| 断言 | 注入形态 | 跑的最窄闸 | 期望 | +|---|---|---|---| +| V1 | T1 挂载行改 `counters_ctx.adventure_bucket = {}`(丢共享引用——复刻副本不同步缺陷类) | 跑 `smoke_all.gd` 单脚本,核对 V1 断言红 | V1 红 | +| V5 | V4/V5 两编排器改传各自新建 level 字典(复刻 :838-841 旧形态跨战不共享) | 跑 `smoke_all.gd` 单脚本,核对 V5 断言红 | V5 红 | +| V9(.tres 侧) | 注释 `validate_trigger_row` 前缀校验分支 | `counter_prefix_fatal_test.gd` 单跑 | 套件转「违规放行」态判红 | +| V9(合成行侧) | 注释 `_push_trigger` 内前缀 assert 行 | T5 孤立验证驱动单跑(输出签名扫描) | assert 签名消失=拦截失效判红 | +| V10 | 任一源文件临时写回一处 `"counters_export"` 引用 | `static_scan.sh` 单跑该 S 段 | 扫描红 | + +**测试方式两分法**:V1–V13 全部=调试接口直改/直调核心层(共享字典注入、`request_dig`/`_judge_seal`/`_emit_round_start` 核心写口直调),不经 UI;V14=用户目检(登记不阻塞,验收时间用户自定)。 + +## 10. 异常分级 + +- **L1 自救**:编译错/笔误级红;孤立验证失败(新类/新函数首跑);复放脚本参数错重跑。 +- **L2 记录继续**:V12 受影响局保守超集判定边界个案(某局归类存疑)——按受影响组从严判读并记录;负面套件在 release 模式 assert 剥离致假绿——换 debug 通道验证并记录(配置问题非代码缺陷)。 +- **L3 停机呈报**:V12 未受影响局出现任何逐位差异(确定性破约);V7/V25 任何一条红(契约 5 破);V13 崩溃;`pain_layers` 行为漂移(契约 8 破);写口语义与现役不一致导致 V1–V8 连带红且无法归因单点。 +- 环境故障(worktree 缓存/资源导入/console exe)按 process-conventions 异常分级自救清单处理。 + +## 11. 代拍板白名单(超清单必呈报) + +1. 新测试函数/夹具变量命名、断言消息文案(编号尾缀〔无状态化 Vn〕已锁)。 +2. 冒烟新段的段落插入位置与段名(须紧邻现役树规则段)。 +3. 静态 `counter_add`/`counter_spend`/`bucket_of` 内部语句序(签名与语义已锁,实现体自由)。 +4. `feats.tres` 行内键序调整(键集与值已锁)。 +5. `effect_engine.gd` 合成行注释的措辞更新(口径已锁:前缀表述)。 +6. 负面套件内诊断文案措辞(退出码协议已锁)。 + +## 12. 待裁点 + +**零待裁点,开工门=U0。** + +本卡全部设计定值承自提案 §7(N1–N6)、§7.7(零采集)、§7.10(缺口闭合),均为「已生效裁定+硬纪律」推导所得并写明依据;其中以下各项带「可否决」标注(提案 §7.9/§7.10.14 同口径),用户审卡时可单独推翻、推翻即回改卡:§7.9 五条(立项判据载体/domain+reset_at 删键/`adventure_counters` 容器名不改/旧档不迁移/两编译名单删除)与 B6(dig_combo 死路删除)。卡片成立还需 grilling 复核通过(零待裁点+验收三问逐条可答已自查,见下)。 + +--- + +## 附:任务卡自审五查记录(2026-10-20 成文自检) + +**grilling 复核轮**:成文后经独立会话对抗复核(新会话视角、不带写卡人假设),五项回炉点已全落——①行号群订正(成员块 :83-88/:84-87、`counters_seed` :255、`EffectEngine.new` :271、合成行 :136-155、注释 :137、rebuild :1610、裸引擎段实数 53 处、合成行字面六处);②V12 具名锚+T7 增锚新鲜度核对步(批前基线码两局配对在先);③V9 assert 侧补孤立验证与变异行;④T5 判定函数名落定 `counter_id_legal`;⑤估时头对齐 T 表加总+超盒切分预案。复核结论「定点回炉后可交用户审」已执行。 + +1. **规格覆盖**:完成定义 1–8 ↔ T 卡映射——1→T2;2→T1;3→T2/T3;4→T1;5→T5;6→T7(V12);7→T3;8→T7(V13)。验收 V1–V14 逐条有落点。✓ +2. **步骤扫描**:各步一动作一核查结果;实现体未写(签名+断言已锁);无「TBD/酌情」句式。✓ +3. **类型一致性**:`EffectContext` 字段名、编排器/LevelRunner 成员名、enc 键名、静态函数签名在 T1/T2/T3/T7 引用处逐字一致(契约 7 锁定)。✓ +4. **审查焦点**:规格暗示的失败模式对照——确定性漂移(V12 未受影响组+锚新鲜度闸)、引用切断(契约 3+V1 变异)、限次失效回退(V5 变异)、加载致命旁路(V9 双侧变异)、死路复活(V10)——均有承载;「同轮 dispatch 内 round 桶清空与订阅行命中并存」的时序语义由 V8+现役特判位置保持承载。✓ +5. **篇幅比例**:本卡以签名/断言/落点为主,无函数体代码块。✓ From f7be1f47c4420394c118c88cbd78c9e647aaf3f9 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 07:39:30 +0800 Subject: [PATCH 10/59] =?UTF-8?q?docs(=E6=95=88=E6=9E=9C=E5=BC=95=E6=93=8E?= =?UTF-8?q?=E6=97=A0=E7=8A=B6=E6=80=81=E5=8C=96=C2=B7=E5=86=99=E5=8D=A1?= =?UTF-8?q?=E8=A1=A5=E4=B8=81):=20grilling=20=E5=AE=A1=E6=9F=A5=E8=BD=AE?= =?UTF-8?q?=E4=BA=8B=E5=AE=9E=E4=BF=AE=E6=AD=A3=E2=80=94=E2=80=94T3=20?= =?UTF-8?q?=E8=A1=A5=20:390=20=E5=9B=9E=E7=81=8C=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E5=88=A0=E9=99=A4=EF=BC=88=E6=BC=8F=E5=88=97=E5=8D=B3=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E6=96=AD=E8=A3=82=E9=9D=A2=EF=BC=89=EF=BC=9BT2/T1=20?= =?UTF-8?q?=E8=A1=A5=20run=5Fledger=20=E5=A4=B4=E6=B3=A8=E4=B8=8E=20level?= =?UTF-8?q?=5Frunner=20:630=20=E8=BF=87=E6=9C=9F=E5=A5=91=E7=BA=A6?= =?UTF-8?q?=E5=8F=A5=E6=B8=85=E7=90=86=E9=9D=A2=EF=BC=88=E3=80=8C=E6=88=98?= =?UTF-8?q?=E6=96=97=E4=BE=A7=E5=8F=AA=E8=B5=B0=20read/append=20=E5=8E=9F?= =?UTF-8?q?=E8=AF=AD=E3=80=8D=E9=9A=8F=20ctx=20=E7=9B=B4=E5=86=99=E5=AD=97?= =?UTF-8?q?=E9=9D=A2=E5=A4=B1=E4=B9=89=EF=BC=89=EF=BC=9BT5=20counter=5Fid?= =?UTF-8?q?=5Flegal=20=E4=BF=AE=E5=9B=9E=E6=8F=90=E6=A1=88=20=C2=A73.3=20?= =?UTF-8?q?=E5=AD=97=E9=9D=A2=EF=BC=88=E4=BB=85=20meta=5F=20=E9=9D=9E?= =?UTF-8?q?=E6=B3=95=E2=80=94=E2=80=94=E3=80=8C=E5=85=B6=E4=BD=99=E6=9C=AA?= =?UTF-8?q?=E7=9F=A5=E5=89=8D=E7=BC=80=E9=9D=9E=E6=B3=95=E3=80=8D=E8=AF=AD?= =?UTF-8?q?=E6=B3=95=E4=B8=8D=E5=8F=AF=E5=88=A4=E5=AE=9A=EF=BC=8C=E6=AE=8B?= =?UTF-8?q?=E5=89=A9=E9=A3=8E=E9=99=A9=E5=BD=92=20V10=20=E6=89=AB=E6=8F=8F?= =?UTF-8?q?=E4=B8=8E=E8=AF=84=E5=AE=A1=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- reports/需求卡片-效果引擎无状态化批-2026-10-20.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/reports/需求卡片-效果引擎无状态化批-2026-10-20.md b/reports/需求卡片-效果引擎无状态化批-2026-10-20.md index e7099b8a..7e8fcc1e 100644 --- a/reports/需求卡片-效果引擎无状态化批-2026-10-20.md +++ b/reports/需求卡片-效果引擎无状态化批-2026-10-20.md @@ -143,7 +143,7 @@ - [ ] 新建 `game/core/effect_context.gd`:`class_name EffectContext extends RefCounted`;四字段 `var round_bucket: Dictionary[Variant, Variant] = {}`(battle_bucket/level_bucket/adventure_bucket 同型);文件头注 ≤8 行两类白名单;跑一次编辑器扫描刷新全局类缓存(code-conventions §4.5) - [ ] `BattleOrchestrator` 增三公开成员:`fx_counters_round`/`fx_counters_battle`(`Dictionary[Variant, Variant]`)+`counters_ctx: EffectContext`;`_init` 内构造 ctx 并挂自有两桶引用 -- [ ] `LevelRunner` 增公开成员 `level_counters: Dictionary[Variant, Variant]`;`_start_battle` enc 增 `"level_counters": level_counters`(`"ledger"` 行 :471 后) +- [ ] `LevelRunner` 增公开成员 `level_counters: Dictionary[Variant, Variant]`;`_start_battle` enc 增 `"level_counters": level_counters`(`"ledger"` 行 :471 后);:630 过期契约注释(「战斗侧只走账类原语,战末 export/开局 seed」)随批改写 - [ ] `begin_battle` :373 后挂载:`counters_ctx.adventure_bucket = _ledger.adventure_counters`;`enc.get("level_counters")` 为 Dictionary 时 `counters_ctx.level_bucket = enc["level_counters"]`(缺省=调试/单场空桶,与 `_ledger` 缺省新账同式) - [ ] `set_fx` 三处扩参:`func set_fx(fx: EffectEngine, ctx: EffectContext) -> void`(action_economy.gd:48/damage_controller.gd:70/reward_economy.gd:23),三协同件各增 `_ctx` 成员;`battle_orchestrator.gd:280-282` 调用点同步 - [ ] 删 `adventure_runner.gd:838-841` `_reset_tree_limited_counters` 与 `:845` 调用点(同批摘除冒烟 `:6125` 直呼——F2 面随 T7 断言同轮) @@ -159,7 +159,7 @@ - [ ] `counter(ctx: EffectContext, counter_id: String) -> int`(读 `bucket_of(ctx, counter_id)`) - [ ] 新增 `static func bucket_of(ctx: EffectContext, counter_id: String) -> Dictionary[Variant, Variant]`:`round_`→round_bucket/`lvl_`→level_bucket/`adv_`→adventure_bucket/其余→battle_bucket(前缀规则唯一出处) - [ ] 新增静态 `counter_add`/`counter_spend`(签名见产出块;算术与阈值闸语义从现役 :228-242 逐字保留);删实例版两方法与 `counters_export`/`counters_seed`(:246-257) -- [ ] `run_ledger.gd` 删 `counters_seed_snapshot`(:36-37)与 `counters_merge_export`(:40-45) +- [ ] `run_ledger.gd` 删 `counters_seed_snapshot`(:36-37)与 `counters_merge_export`(:40-45);头注契约句「战斗侧只走 read/append 两族原语」同步改写(ctx 直写后字面失义、签名可见显式引用的立意由 EffectContext 承接) - [ ] `DO_KEYS` 删 `"domain"`/`"reset_at"`(:72-75) - [ ] 孤立验证:裸引擎 rig `EffectEngine.new(null)`+自建 ctx,合成一行 counter_add 行 dispatch→静态写口→counter 读回一致 @@ -171,7 +171,7 @@ - [ ] `damage_controller.gd`::78 dispatch 加 ctx;:345 读改 `EffectEngine.counter(_ctx, ...)`;:351/:464 写口静态化 - [ ] `reward_economy.gd`::65 dispatch 加 ctx - [ ] `grant_segment.gd`::103/:205 读口 ctx 化(经 `oc.counters_ctx`);:327 `_apply_counter_hit` 内写口改静态(调用点 :66/:122/:156/:215/:264 零改动);:54/:61/:62 `combo_cap` 收集与实参删除 -- [ ] `battle_orchestrator.gd`::88 `_fx_emit` 加 `counters_ctx`;:714 受理闸改 `EffectEngine.counter_spend(counters_ctx, ...)`;:635-647 删 `dig_combo` 死读数+combo 加成分支+`_feat_yield_adjust` 第五参(§7.10.14,零行为差);:1122-1123 战末导出两行删除(:1118-1121 bonus_delta 汇入保留——那是 N6 留编排器的运行态,不是计数器) +- [ ] `battle_orchestrator.gd`::88 `_fx_emit` 加 `counters_ctx`;:714 受理闸改 `EffectEngine.counter_spend(counters_ctx, ...)`;:390 回灌调用 `_fx.counters_seed(_ledger.counters_seed_snapshot())` 连同 :389 注释行删除;:635-647 删 `dig_combo` 死读数+combo 加成分支+`_feat_yield_adjust` 第五参(§7.10.14,零行为差);:1122-1123 战末导出两行删除(:1118-1121 bonus_delta 汇入保留——那是 N6 留编排器的运行态,不是计数器) - [ ] 孤立验证:单场编排 rig begin_battle→request_dig 一次→`run_ledger.adventure_counters` 立即可见写入(无战末时点依赖) ### T4 round 泛化+宿主清零确认(0.25d) @@ -186,7 +186,7 @@ **取用**:T2 的 `bucket_of` 前缀规则。**产出**:加载期前缀致命通道(V9)。 -- [ ] 新增静态判定函数 `static func counter_id_legal(counter_id: String) -> bool`(名字锁定):无前缀=true(battle);`round_`/`lvl_`/`adv_` 前缀=true;其余带前缀形态(`meta_` 等)=false——前缀规则与 `bucket_of` 同源(bucket_of 解析为 battle 而 id 首段含 `_` 即非法,单一规则表) +- [ ] 新增静态判定函数 `static func counter_id_legal(counter_id: String) -> bool`(名字锁定;规则=提案 §3.3 字面):`round_`/`lvl_`/`adv_` 前缀=true;`meta_` 前缀=false(引擎不接存档级);其余=true(无前缀落 battle——「其余未知前缀也非法」在语法上不可判定:一切 snake_case id 都以「词_」形态开头,禁自造封闭词表=第二事实源红线;自造新前缀静默落 battle 的残余风险由 V10 扫描与评审承担) - [ ] `validate_trigger_row` 增分支:`do` 含 `counter_id` 时校验,非法→errs 追加 `{"category": "enum", ...}` 违例 - [ ] `_push_trigger` 增 assert:`do` 含 `counter_id` 时同规则 assert(树合成行路径,写错调试期致命;assert 消息以 `[效果引擎]` 前缀起头,供孤立验证扫描) - [ ] 孤立验证(V9 assert 侧):`--headless --script` 最小驱动 rebuild 带「counter_id 带非法前缀」的合成行——输出扫到 `[效果引擎]` assert 签名=拦截在位(debug 通道;assert 不改退出码,判据=输出签名扫描) From ed19453d25694b0df29d5a129512dc150de6a787 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 14:54:53 +0800 Subject: [PATCH 11/59] =?UTF-8?q?chore(=E6=89=B9=E5=90=8E=E6=94=B6?= =?UTF-8?q?=E5=B0=BE):=20=E8=BF=AD=E4=BB=A3=2027=20=E4=BA=A7=E5=87=BA?= =?UTF-8?q?=E7=89=A9=E9=80=80=E5=BD=B9=E2=80=94=E2=80=94=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E6=8A=A5=E5=91=8A=E4=B8=8E=E6=8E=A2=E9=92=88=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E5=AF=B9=E7=85=A7=E6=8C=89=E5=90=B8=E6=94=B6=E5=8D=B3=E6=AD=BB?= =?UTF-8?q?=E5=88=A0=E9=99=A4=EF=BC=88=E5=8F=8D=E5=93=BA=E7=82=B9=E5=B7=B2?= =?UTF-8?q?=E8=90=BD=20architecture/code-conventions=202026-10-17=20?= =?UTF-8?q?=E7=89=88=E3=80=81=E8=BF=BD=E8=AE=A4=E5=8D=95=E5=8D=81=E4=BA=94?= =?UTF-8?q?=E9=A1=B9=E5=B7=B2=E8=BF=BD=E8=AE=A4=E3=80=81=E7=9B=AE=E6=A3=80?= =?UTF-8?q?=E5=B7=B2=E7=99=BB=E8=AE=B0=2007=20=E3=89=96=E3=80=81=E8=A7=82?= =?UTF-8?q?=E5=AF=9F=E4=B9=89=E5=8A=A1=E5=B7=B2=E8=BF=81=2006=EF=BC=89?= =?UTF-8?q?=EF=BC=9Broadmap=20=E8=BF=AD=E4=BB=A3=2027=20=E8=A1=8C=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E6=8A=A5=E5=91=8A=E5=88=97=E6=94=B9=E9=80=80=E5=BD=B9?= =?UTF-8?q?=E4=BF=9D=E7=95=99=E5=AD=97=EF=BC=8Creports/README=20=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B=E6=B3=A8=E8=AE=B0=E9=80=80=E5=BD=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- reports/README.md | 2 +- reports/iter27-实现报告-2026-10-14.md | 96 ----------------------- reports/iter27-探针迁移对照-2026-10-14.md | 28 ------- roadmap.md | 2 +- 4 files changed, 2 insertions(+), 126 deletions(-) delete mode 100644 reports/iter27-实现报告-2026-10-14.md delete mode 100644 reports/iter27-探针迁移对照-2026-10-14.md diff --git a/reports/README.md b/reports/README.md index e3e4d205..7efc21c6 100644 --- a/reports/README.md +++ b/reports/README.md @@ -10,7 +10,7 @@ | `iter-实现报告-<日期>.md` | 各任务卡状态、实机目检总清单、遗留读数义务 | 迭代批 | | `iter-代拍板-<日期>.md` | 批内 agent 替你拍的决定清单,等你追认或推翻 | 迭代批 | | `iter-反哺点-<日期>.md` | 需要写进 `design/` 权威文档的点,逐条列清"哪个文件哪一节、改成什么、依据是什么" | 迭代批 | -| `iter-<交付物名>-<日期>.md` | 需求卡片点名的其它交付物(例:`iter27-探针迁移对照-2026-10-14.md`=11 个探针的成员依赖面清单) | 迭代批 | +| `iter-<交付物名>-<日期>.md` | 需求卡片点名的其它交付物(例:`iter27-探针迁移对照-2026-10-14.md`=11 个探针的成员依赖面清单,已随迭代 27 收尾退役) | 迭代批 | ## 不放什么 diff --git a/reports/iter27-实现报告-2026-10-14.md b/reports/iter27-实现报告-2026-10-14.md deleted file mode 100644 index 7a2da38d..00000000 --- a/reports/iter27-实现报告-2026-10-14.md +++ /dev/null @@ -1,96 +0,0 @@ -# 迭代 27 实现报告——代码架构技术债修复批(五波全量入库) - -- 日期:2026-10-14(单会话 /goal+iter U0 交付,worktree g-plan2-iter27-techdebt 分支 iter27-techdebt-20261014) -- 需求卡片:已退役(git 历史可考)——原「代码架构技术债修复批」v1.2——三点待裁 2026-10-14 用户三裁全按推荐案:①SaveManager/MetaProgression=第三个 autoload/②Ledger=单类持四账/③_settle=审计五段) -- 来源审计:代码架构与实现质量审计报告-2026-10-14(双席基线 97de02c;**本批收口时按退役规则 git rm——吸收即死,结论迁本报告与卡片**) -- 核心验收(V1):**重构前后同种子完整局输出逐位一致**——parity_anchor 三变体(base/attune/shop)×40 局×RUNSUM+JSONL 剔 ts 双面哈希对拍,**五波出口五跑全同**(锚冻结于 T0,种子面 71000/72000/73000) - -## 一、五波交付 - -### 波一 场景拆分+局生命周期物化(P0-1/P0-2,7a0d57d) - -- 三屏壳场景 `presentation/scenes/`:menu_screen/camp_screen/adventure_screen(内含 level_map/battle 两容器)——视图代码原样构建(装配器/视图类零 .tscn 化,契约 2);组合根句柄全部保留(探针挂载假设 main.X 一级路径零迁移);树序=屏壳在前全模态之下(视觉共存对逐对验算:legend/battle、debug/level_screen、shop/level_screen 等全部保序)。 -- 会话物化 `run_scope.gd`:adventure/runner/settlement/局态旗/账本随会话节点承载;`_begin_session` 建会话(_ready 即建闲时态=永非 null)、终局整节点 queue_free()——`_reset_run_scope` 三项+`_on_battle_end_continue` 置空四件手工清单消亡。 -- SaveManager/MetaProgression 升格 autoload(裁点①甲;类名加 Core 后缀沿 RngService 先例);探针隔离改 attach_path 原地重置(set_master_seed 先例);**发现并修复**:屏壳根全屏 Control 默认 STOP 吃掉下层模态鼠标输入(ui_input 实证)——三屏壳根 mouse_filter=IGNORE+V2 回归闸。 -- V2 屏壳独立实例化 11 断言+V3 两连局复位 11 断言进 smoke。 - -### 波二 _settle 五段拆 Segment(P1-1,26301ba) - -- `core/settlement/` 五段类:GrantSegment(授予段体+旗判随段迁入+counter_add 五位/grant_material 三位分支单点化)/AuraSegment/CombatSegment/DecaySegment/VerdictSegment(返回裁定,终局早退语义留宿主);编排器 1725→1325 行退为段序编排+行发射原语单点。 -- 姊妹病灶:`_resolve_hero_attack` 148 行拆四步(ctx 命中面→基值装配→掷点兑现→交付),ctx/redemption 字典穿线算序逐字保留。 -- V4 settle_segments_test 16 断言进 run_all。 - -### 波三 账本收口(P1-2/P1-3/P1-4,6fd7d78) - -- `core/run_ledger.gd` RunLedger 单类持四账(裁点②甲):attune_charges/vision_counter/adventure_counters/bonus;战斗侧只拿 read/append 原语;AR 持账→LR set_run_ledger→enc 单键下传;编排器三裸引用成员退役;调试/单场缺省新账=零扰动面(vision_counter 缺省空=不计,原 enc 缺键守卫语义保留)。 -- 刷新双账:main 副本删除;presentation_snapshot 成文面升键 refresh_used(can_refresh 邻位)——HUD 余量/遥询单源读快照;V5 快照一致性断言×3。 -- GP 影子账:summary 增 gp_final 键(close_wallet 清账前快照);gp_shadow_ledger.gd 全件退役;终局面板 GP 行取数=summary 键;ui_probe 断言换代。 - -### 波四 组合根可测化+模态协议内聚(P1-5/P2-7,8b9e556) - -- **重估结论(卡片 T4 前置义务)**:场景拆分落地后,模式状态机已随 RunScope 物化、屏构建已随屏壳迁出——抽取面收敛为**模态编排域**:`modal_flow.gd` ModalFlow 纯逻辑类(依赖仅 ModalStack+查询 Callable,审计处方形态)——开合编排(挂起兜底/排播排空/遮挡记账/开合同步)/输入锁谓词(三例外注入)/双形制角标谓词。 -- **V6 测试抓出并修正一处真分歧**:挂起兜底递归后误加 return(原 main 语义=先结挂起后继续开本层两拍都走)——单测缝的结构价值实证。 -- ModalStack 互斥域随层登记:register(m, tags)+TAG_NON_LOCKING/TAG_SCREEN_STATE 封闭词表+has_open_excluding_tags 组查询;原调用点排除式拼装(:404-409 输入锁等五处)退役;main._modals=flow.stack(ui_struct _list 断言缝保留)。 -- 控制器构造收拢 context:curio 16 参→CurioFlowContext/camp 13 参→CampFlowContext(字段逐一同名,控制器可独立实例化)。 - -### 波五 类型闸+卫生件(P1-6/P2 组,b605022+T6 笔) - -- 类型闸:`tools/audit_type_hints.py` 机器闸(R1 无类型容器注解/R2 有值返回缺类型/R3 参数缺类型+行级白名单通道);368 处容器注解机械参数化(Array[Variant]/Dictionary[Variant, Variant] 零行为面)、13 处参数真类型;project.godot 拉起 untyped_declaration=1;static_scan 新 S9 规则。 -- 卫生件:死代码 13 函数删除(审计 16 处复核后其中 ui_kit:486 一处经实读为现役非死码,见追认单)+FeatsEngine 整文件退役;字符串 Callable×10 位换方法引用形态(编译期方法存在性校验);冒险状态机/standee 主角三态 enum 化(外部 String 契约逐位一致);ConfigDB `_fatal` 退出归根(核心层去 quit/crash,置 `_fatal_flag`,退出决策归组合根既有 fail-fast 通道)+resolver 诊断/数据通道全面 Callable 化(ConfigDb↔Resolver 类型环断根)。 - -## 二、闸记录(每波出口+批末) - -| 闸 | 基线(T0 冻结) | 波一 | 波二 | 波三 | 波四 | 波五 | -|---|---|---|---|---|---|---| -| 逐位一致对拍(V1 核心) | 锚冻结 | ✓ 全同 | ✓ 全同 | ✓ 全同 | ✓ 全同 | ✓ 全同 | -| 冒烟 | 1055/0 | 1077/0 | 1077/0 | 1079/0 | 1079/0 | 1081/0 | -| run_all | 25 套 | 25 | 26 | 26 | 27 | 27 | -| probe_gate --click | 绿 | 绿 | 绿 | 绿 | 绿 | 绿 | -| render_gate golden | 0.00% | 0.00% | 0.00% | 全绿 | 全绿 | 全绿 | -| static_scan | (历史 cd 错位恒跳过) | — | — | — | — | S1/S2/S4/S9 全绿 | - -批末(T6 后)run_all 27 套全绿+冒烟 1081/0+probe/render 全绿+对拍全同(T6 对拍见 /tmp/parity_check6.log 记录,exit 0)。 - -## 三、代拍板追认单(白名单九项执行实录+计划外决断) - -> **追认结果(2026-10-17 用户令)**:以下十五项**全部同意,无修改意见**——第 1–9 项白名单执行实录、第 10–15 项计划外决断均认作本批既定做法。第 7 项附带的元素精化(`Array[Variant]`→具体元素型)仍是后续批的渐进面,不随本追认提前。第 15 项的取数面换代已生效。 - -1. **屏场景命名/落位**(白名单①):`presentation/scenes/{menu,camp,adventure}_screen.tscn`——三屏壳与卡片三屏一一对应。 -2. **屏壳内部分层**(白名单②):adventure 屏壳内 battle_root+level_screen 平级(无同时可见态,层内先后零视觉差)。 -3. **Segment 五类命名/落位**(白名单③):`core/settlement/{grant,aura,combat,decay,verdict}_segment.gd`,类名 XxxSegment。 -4. **Ledger 命名/原语形状**(白名单④):`core/run_ledger.gd` RunLedger;原语=attune_charge_has/set/consume、vision_count_add、counters_seed_snapshot/merge_export、bonus_add_axis(各站点原语义逐字收拢)。 -5. **run-scope 物化形态**(白名单⑤):RunScope Node 挂 main;_ready 即建闲时态(永非 null——全组合根免空判);会话更替=旧节点 queue_free+新节点同拍建。 -6. **探针迁移最小改动**(白名单⑥):组合根句柄保留策略使 10 探针中 7 个零迁移、3 个仅 run_scope 路径换代;pacing 测试改 attach 隔离。 -7. **类型标注写法**(白名单⑦):368 处机械参数化取 `Array[Variant]`/`Dictionary[Variant, Variant]` 零行为面口径——**元素精化(如 Array[Dictionary])留后续批渐进**(机器闸已封住新增无类型)。 -8. **死代码删除切分**(白名单⑧):随 T6 单笔提交。 -9. **enum 命名**(白名单⑨):adventure `State`/standee `HeroState`(+_HS_NAME/_HS_VALUE 双向映射常量)。 -10. **〔计划外〕P2-2 autoload 直取降格实现**:审计处方「编译期全局名」与本仓 --script 模式编译器不解析裸 autoload 标识符**硬冲突**(run_all.gd 头注在案+pacing 实测 Parse Error)——降格为路径常量单点(AUTOLOAD_PATH_* 四常量)+T1 读视图属性;拼写风险收敛一处,类型面保留。 -11. **〔计划外〕board_generator 四 db 参白名单**:generate/_attempt/legality/_finalize 的 db 参保持鸭子型(测量面 _BoardRowStub 冒烟夹具注入,typed 参拒 stub)——`# type-hint: ignore` 显式白名单通道首用。 -12. **〔计划外〕static_scan 历史 cd 错位修复**:9-24 布局迁移后 `dirname/..` 落 game/ 致 `game/core` 守卫恒跳过=静默空转遗产——修 `/../..` 后 S1-S4/S9 首次实跑,暴露并处置两笔存量(S1/S2 main `_seed_value` randi=文档化豁免面→`rng-seed-exempt` 标记豁免通道;S9 即本批闸)。 -13. **〔计划外〕V6 测试抓出挂起兜底分歧**:ModalFlow 初版在挂起兜底后误加 return(原 main 语义两拍都走)——以原语义为准修正;该处即单测缝价值的直接实证。 -14. **〔计划外〕审计「死代码 16 处」复核为 13 处**:ui_kit.gd:486 一处实读为现役代码(审计抽样误差),不删;其余 12 函数+FeatsEngine 整文件照删。 -15. **〔计划外〕刷新遥测取数面换代**:`ux_refresh_attempt` 的 round_refresh_index 从 main 副本改读快照(P1-2 连带,载荷键与数值语义零变化)。 - -## 四、GDD 反哺点(两条,已登记 06,待用户逐点裁决另批落文) - -| # | 文档 | 反哺点 | -|---|---|---| -| 1 | design/dev/architecture/architecture.md | 场景分层陈述(三屏壳+组合根句柄面);会话生命周期(RunScope 物化+_begin_session/_end_session 语义);结算五段 Segment 结构(core/settlement/);RunLedger 四账所有权模型;ModalFlow 模态编排层与互斥域 tags 协议——architecture 现行陈述均滞后于实态 | -| 2 | design/dev/code-conventions.md | §4 语言纪律机器化(S9+audit_type_hints.py 三规则);`:= {}` 推断形态=类型推断合法面不算债的口径;`# type-hint: ignore` 行级白名单通道;`# rng-seed-exempt` S1/S2 标记豁免通道;--script 模式禁裸 autoload 标识符纪律(新);Variant 参数化口径与元素精化后续 | - -## 五、实机目检总清单(登记 07 ㉖——真人检测不阻塞,2026-10-12 立规) - -1. 全流程操作观感零变化走查:开始菜单→营地(四柜台)→开新冒险→选路→战斗(挖/旗/刷新/停手)→三选一→商店→Boss→终局逐屏过一遍(场景拆分+会话物化后唯一人闸面)。 -2. 续玩断点恢复:停点退出→继续上局(断点文案/恢复落点)。 -3. 调试浮窗对局中可开不锁棋盘(:407-408 事故回归——互斥域 tags 化后行为钉面)。 -4. 刷新按钮余量显示与受理一致(双账删副本后 HUD 单源读快照)。 -5. DS_DEBUG=1 启动即开浮窗+两屏角标(同步面随 ModalFlow 迁移)。 - -## 六、残留与去向 - -- 残留人闸:07 ㉖ 五件(登记不阻塞)。 -- **卡片核对补登(2026-10-15)**:逐条核对卡片 §2/§4/§6/§7 兑现面,补齐三项——①V8 卫生 grep 断言落地(smoke `_smoke_hygiene_gates`:字符串 Callable 产品码零命中/FeatsEngine 文件退役/死代码抽查/GP 影子账零残留);②卡片 §4「长函数 17 个登记 06 观察」+§2.3「lambda 连接 76 处登记防回归」两条义务补登 06(17 中 3 件已随波一/二消解,余 14 件备忘);③漏网字符串 Callable×2 补装(config_db resolver 通道——T6 新增位点,追认单#15 换装面覆盖)+main 头注死引用清理。核对结论:§1 五波/§3 六契约/§6 T0-T7/§7 V1-V9 其余条目全部兑现(详见各波闸记录)。 -- 代拍板追认单十五项(上表)待用户逐项追认。 -- GDD 反哺点两条(06 在册)待裁决另批落文。 -- 审计报告本体已按退役规则 git rm(吸收即死;修正后计数已由需求卡片 v1.2 承载)。 -- 元素精化(Array[Variant]→具体元素型)为类型闸后续渐进面(06 反哺点②附带)。 diff --git a/reports/iter27-探针迁移对照-2026-10-14.md b/reports/iter27-探针迁移对照-2026-10-14.md deleted file mode 100644 index bbbcd9e9..00000000 --- a/reports/iter27-探针迁移对照-2026-10-14.md +++ /dev/null @@ -1,28 +0,0 @@ -# 迭代 27 T0 交付:smoke 探针挂载假设对照表(2026-10-14) - -卡片 T0.3 交付物。11 个挂载面 = 10 个 smoke 探针 + 1 个单测套件(pacing_queue_test,全库唯一直接 load main.tscn 的单元测试)。 -迁移原则(卡片 🔴 探针契约零破坏):**「实例化 main.tscn 得到完整产品树 + 组合根 API」这一挂载假设本身保留**—— -场景拆分后 main.tscn 仍是组合根(屏场景为其子节点挂载),探针入口零改动; -迁移面 = 探针内部对 main 私有成员的树寻址/状态探视,随成员落位逐个改写(改写即新结构的回归断言)。 -另两个挂载假设探针(adventure_monte_carlo/level_autoplay,SceneTree 直驱 level_runner 不挂 main.tscn)不在迁移面。 - -| # | 探针 | 挂载行 | 挂 main.tscn 得到什么 | 成员依赖面(实测 grep) | 迁移方向(T1 落位后改写) | -|---|---|---|---|---|---| -| 1 | ui_probe.gd | :15 | 完整产品树+驱动 `_start_adventure_from_menu()`(唯一试玩入口) | `_start_overlay/_battle_root/_row_queue/_debug/_is_settling/_on_adventure_finished/_on_camp_closed/_on_wallet_changed/_reset_run_scope/_adventure_gp_final/_adventure_gp_view/_close_modal` + `adventure/ap_bar/board_view/board_zone/camp_overlay/db/debug_overlay/info_panel/level_screen/log_view/meta/runner/settlement/stage` | 屏成员→屏场景属性路径;局态成员→run-scope 节点路径;`_reset_run_scope` 断言随手工清单消亡换代为 run 节点释放断言 | -| 2 | ui_click_probe.gd | :45 | 全输入链走查(行进/战斗/营地/商店点击 10935 预算) | 最广:`_adventure_mode/_battle_root/_camp_data/_end_overlay/_exit_level_screen/_input_locked/_inter_overlay/_last_gain_amount/_locked_click/_on_camp_closed/_refresh_resume_button/_refresh_used_round/_row_queue/_settlement_stop_pending/_start_adventure_from_menu/_start_overlay` + 全部屏成员 | `_input_locked` 输入锁随 T4 模态协议内聚落位;`_refresh_used_round` 随 T3 双账删除改快照通道断言;余同 #1 | -| 3 | ui_struct_probe.gd | :25 | 模态栈纪律走查(开合/遮挡/输入锁) | `_close_debug_overlay/_end_overlay/_gp_summary_text/_level_active/_modals/_on_camp_closed/_on_career_closed/_on_settings_closed/_on_status_closed/_open_modal/_open_settings/_open_status_panel/_refresh_resume_button/_resume_from_menu/_show_debug_overlay/_start_adventure_from_menu/_start_overlay` + 屏成员 | `_modals`(ModalStack)随 T4 内聚后寻址换代;模态层清单断言随屏场景化改挂屏壳 | -| 4 | ui_layout_probe.gd | :17 | 四区布局几何断言 | `_start_adventure_from_menu/board_view/board_zone/debug_overlay/info_panel/get_child/get_children/save_manager/stage` | board_zone/info_panel/stage 随屏场景化改屏壳属性路径;`get_child` 序数寻址须换名寻址(子场景化后序号漂移) | -| 5 | ui_input_probe.gd | :27 | 输入锁+宝珠辉光链路 | `_input_locked/_start_adventure_from_menu/_sync_treasure_glow/board_view/board_zone/build_adventure_params/debug_overlay/runner/save_manager/settlement/status_panel` | `_sync_treasure_glow`/`build_adventure_params` 随局态物化落位;余同 #1/#2 | -| 6 | ui_audit_probe.gd | :27 | 全屏巡检(12 模态层/入口可达) | `_close_debug_overlay/_end_overlay/_on_settings_closed/_open_settings/_refresh_resume_button/_show_debug_overlay/_start_overlay/board_view/camp_overlay/confirm_dialog/curio_overlay/legend_overlay/level_screen/save_manager/shop_overlay` | 模态层清单随屏场景化改挂屏壳;余同 #1 | -| 7 | ui_tune_probe.gd | :36 | 调试浮窗只读巡检(种子框/批量模拟) | `_close_debug_overlay/_input_locked/_seed_value/_show_debug_overlay/_start_adventure_from_menu/_start_overlay/adventure/board_zone/confirm_dialog/db/debug_overlay/level_screen/save_manager/settlement` | `_seed_value` 随种子框落位改路径;debug_overlay 归属屏待 T1 定(全局层 vs 屏内层) | -| 8 | shot_probe.gd | :35 | 截图(四屏+营地/设置) | `_start_overlay/board_zone/camp_overlay/career_overlay/level_screen/settings_overlay/settings_store/stage/status_panel` | 屏成员→屏场景路径;settings_store 随升格 autoload 改全局访问 | -| 9 | fx_shot_probe.gd | :28 | 特效截图(棋盘 fx) | `_start_overlay/level_screen/settings_store/settlement` | 同 #8 | -| 10 | t17_defer_probe.gd | :15 | 延迟模态时序断言(结算行分帧) | `_deferred_modal/_end_overlay/_row_pacer/_start_overlay/db/level_screen/meta/save_manager/settings_store/settlement` | `_row_pacer/_deferred_modal` 随 T4 模态协议落位;meta 随升格 autoload 改全局 | -| 11 | tests/unit/presentation/pacing_queue_test.gd | :19 | 行队列节奏单测(真实冒险至首战结算) | `_flush_row_queue/_refresh_resume_button/_row_queue/_start_adventure_from_menu/adventure/db/level_screen/log_view/meta/pace_delay_for/runner/save_manager` | `_row_queue/_flush_row_queue/pace_delay_for` 随 T4 抽取落位(该单测即 V6 新纯逻辑类直接 new() 的前哨);余同 #1 | - -**共性迁移点**(T1 施工照单改写,改写后逐探针全绿=V2 闸): -1. `meta`/`save_manager`/`settings_store` → 裁点① 第三/四 autoload 后改全局名访问(探针里的 `main.meta` 全数换代)。 -2. `runner/adventure/settlement/_adventure_mode/_row_queue` 等局态 → run-scope 节点(`main.run_scope.X` 形态,命名属代拍板白名单#5)。 -3. `_start_overlay/camp_overlay/level_screen/...` 屏成员 → 屏场景属性(组合根保留装配属性,路径一级化)。 -4. `get_child`/子序数寻址(ui_layout #4)→ 名寻址(子场景化后序数漂移是 breaking 面)。 -5. 手工复位断言(ui_probe `_reset_run_scope`)→ run 节点 `queue_free()` 复位断言(V3 配套)。 diff --git a/roadmap.md b/roadmap.md index 6a21bb60..639fee5b 100644 --- a/roadmap.md +++ b/roadmap.md @@ -60,7 +60,7 @@ | 迭代 24 | 已完成(2026-10-13) | 已退役(git 历史可考) | 2026-10-13 | — | 已退役(git 历史可考) | | 迭代 25 | 已完成(2026-10-13) | 已退役(git 历史可考) | 2026-10-13 | — | 已退役(git 历史可考) | | 迭代 26 | 已完成(2026-10-14) | 已退役(git 历史可考) | 2026-10-14 | — | 已退役(git 历史可考) | -| 迭代 27 | 已完成(2026-10-14) | 已退役(git 历史可考) | 2026-10-14 | — | reports/iter27-实现报告-2026-10-14.md | +| 迭代 27 | 已完成(2026-10-14) | 已退役(git 历史可考) | 2026-10-14 | — | 已退役(git 历史可考) | | 迭代 28 | 已完成(2026-10-15) | 已退役(git 历史可考) | 2026-10-15 | — | reports/iter28-实现报告-2026-10-15.md | | 迭代 29 | 已完成(2026-10-16) | 已退役(git 历史可考) | 2026-10-16 | — | reports/iter29-实现报告-2026-10-16.md | | 迭代 30 | 已完成(2026-10-17) | 已退役(git 历史可考) | 2026-10-16 | — | reports/iter30-实现报告-2026-10-17.md | From f8191a3bc6716102a7803cfa85a9d3348a3bb629 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 14:59:04 +0800 Subject: [PATCH 12/59] =?UTF-8?q?chore(=E6=89=B9=E5=90=8E=E6=94=B6?= =?UTF-8?q?=E5=B0=BE):=20=E8=BF=AD=E4=BB=A3=2028=20=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E6=8A=A5=E5=91=8A=E9=80=80=E5=BD=B9=E2=80=94=E2=80=94=E5=90=B8?= =?UTF-8?q?=E6=94=B6=E5=8D=B3=E6=AD=BB=E5=88=A0=E9=99=A4=EF=BC=88=E5=8F=8D?= =?UTF-8?q?=E5=93=BA=E7=82=B9=E4=B8=89=E6=9D=A1=E5=B7=B2=E8=90=BD=E6=96=87?= =?UTF-8?q?=20architecture=202026-10-17=20=E7=89=88=E3=80=81=E8=BF=BD?= =?UTF-8?q?=E8=AE=A4=201=E2=80=9313=20=E5=B7=B2=E5=90=8C=E6=84=8F=E3=80=81?= =?UTF-8?q?#14=20=E5=BE=85=E8=A3=81=E5=B7=B2=E8=BF=81=2006=E3=80=81t17=5Fd?= =?UTF-8?q?efer=20=E5=AD=98=E9=87=8F=E7=BA=A2=E5=B7=B2=E6=B6=88=E8=A7=A3--?= =?UTF-8?q?full=20=E7=8E=B0=E7=BB=BF=E3=80=81=E7=9B=AE=E6=A3=80=E5=B7=B2?= =?UTF-8?q?=E7=99=BB=E8=AE=B0=2007=20=E3=89=97=EF=BC=89=EF=BC=9Broadmap=20?= =?UTF-8?q?=E8=BF=AD=E4=BB=A3=2028=20=E8=A1=8C=E5=AE=9E=E7=8E=B0=E6=8A=A5?= =?UTF-8?q?=E5=91=8A=E5=88=97=E6=94=B9=E9=80=80=E5=BD=B9=E4=BF=9D=E7=95=99?= =?UTF-8?q?=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- reports/iter28-实现报告-2026-10-15.md | 194 -------------------------- roadmap.md | 2 +- 2 files changed, 1 insertion(+), 195 deletions(-) delete mode 100644 reports/iter28-实现报告-2026-10-15.md diff --git a/reports/iter28-实现报告-2026-10-15.md b/reports/iter28-实现报告-2026-10-15.md deleted file mode 100644 index 3eacf186..00000000 --- a/reports/iter28-实现报告-2026-10-15.md +++ /dev/null @@ -1,194 +0,0 @@ -# 迭代 28 实现报告——启动装配与生命周期验收补全批(六任务全量入库) - -**日期**:2026-10-15 **分支**:iter28-bootlife-20261015(worktree `g-plan2-iter28-bootlife`,基点 39c6544) -**需求卡片**:已退役(git 历史可考)——原「启动装配与生命周期验收补全批」v1.0(零待裁点,用户预批连做全批,不入 git) -**一句话**:把「启动后玩家该看到什么、状态对象何时该活何时该死」从口头约定变成**可执行验收函数**,并逐条用变异实验证明这些函数真能抓住对应缺陷。 - ---- - -## 一、六卡交付 - -| 卡 | 内容 | 提交 | -|---|---|---| -| T0 | worktree + 基线三查 + 运行期树序实采(临时探针两枚,采完即删) | 无产物(定义面已在前置笔 39c6544) | -| T1 | 装配语义合同单点化 + 装配顺序修复 + V2 断言重写 | `6f71509` | -| T2 | boot 链路时序后置条件(`_smoke_boot_chain`) | `a35581e` | -| T3 | 生命周期存活性矩阵(`_smoke_lifecycle_matrix`) | `77075e6` | -| T4 | 渲染面内容断言三件(探针自检 + 墨色判据 + 启动态菜单 golden) | `67342c6` | -| T5 | 变异验证(横切,六次注入;**零提交——注入即还原**) | 无提交(见 §五) | -| T6 | 规范三处落文 + 机械面文档同步闸 | `db1bf42` | -| T1 补 | 类型闸 S9 归零(`main.gd` 合同装配容器注解) | `140e440` | - -### T0 开工基线与事实复核 - -基线冻结:冒烟 **1086/0**(roadmap 与卡片所记 1081 系 iter27 补遗批 `d5eea25` +V8×5 未回写,以实跑为准,**已随本批回写**)、run_all **27 套**全绿、probe_gate --click 全绿残留 0。 - -运行期实采修正了计划书与卡片的三处描述偏差(按「诊断订正」惯例以代码/运行期为准): - -1. **屏壳是容器、不当「顶层可见层」候选**(卡片诊断订正①,运行期实证):三屏壳根均 `MOUSE_FILTER_IGNORE` 纯容器,camp 壳 boot 态 `visible=true` 但成员恒隐;裸树遍历自顶向下会先命中透明壳。断言改为遍历合同**内容层**候选集。 -2. **`_row_pacer` 句柄数**(卡片诊断订正②):计划书称 6 视图句柄,实查 5 + 2 Callable。 -3. **`main.gd:378` 十二模态登记数组**形态与卡片描述有差异——合同常量按运行期实采自行定义为 **16 层自洽表**(含 host 宿住层、shell 屏壳占树位两类特例)。 - -T0 临时探针 `t28_treeorder_probe.gd` / `t28_treeorder_probe2.gd` 采完即删,未提交。 - -### T1 装配语义合同单点化 + 顺序修复 + V2 断言重写 - -- **合同常量 `LAYER_CONTRACT`**(`main.gd`)=全仓唯一事实源:16 层(屏壳 shell / 模态 modal / 全屏态 state / 非视觉 node),带 `tags`(模态互斥域)、`host`(宿住层:level_screen 宿冒险屏壳)、`shell`(屏壳占树位、成员占登记位:camp_overlay/camp_screen)四类字段。树序=登记序=z 序同源派生。 -- **唯一落位口 `_apply_layer_contract()`**:按合同序 `move_child(node, slot)` + `_register_modal(member, tags)`;删除了原先散落在 `_build_ui` 的两处 `move_child`(camp 屏壳插位、curio 对位)。新增 `_layer_node(key)` 查表寻址函数。 -- **装配顺序修复**:`_adventure_screen` 先实例化挂树、`_menu_screen` 后挂——修复坏事实①「菜单屏先挂垫底被冒险屏盖死,F5 见战斗界面」。 -- **V2 断言重写**(坏事实②:旧断言把错误顺序写成期望值,测试在保护 bug):删除三条裸下标断言(`kids.find(_menu_screen)==0 and kids.find(_adventure_screen)==1` 等),改为 - - **V1a** 启动态顶层可见层=start_overlay(内容层遍历,屏壳不当候选) - - **V1b** 语义关系:菜单屏壳树序 > 冒险屏壳树序 - - **V1c** 合同树序链逐对保序(运行期树序 == `LAYER_CONTRACT` 序) - - **V1d** 落位单口源码断言(`_apply_layer_contract` 函数体之外 `move_child(` 计数 == 0) - - 场景探针同步:`ui_struct_probe` 新增 `_modal_registry_contract`(登记序==合同模态序逐位点名、直接子层树序==合同序、level_screen 宿主特例、camp 屏壳夹位特例),旧 `_career_registry_contract` 同批退役。 - -### T2 boot 链路时序后置条件 - -新增 `_smoke_boot_chain`,**十断言**(卡片写「六断言」,实施期按可断言面扩为十):ConfigDB 就绪且表已载 / 音量与减动效引擎态 == settings_store 现值 / start_overlay 可见 / **续玩钮态 == 断点在档态(boot 路径关系判据 + 隔离新档双向三子态:无断点隐、合成断点显、清断点回隐)** / run_scope 闲时会话在树 / 调试浮窗态 == DS_DEBUG 门控。存档隔离走 `attach_path("user://smoke_boot_chain.json")`。 - -### T3 生命周期存活性矩阵 - -新增 `_smoke_lifecycle_matrix`,**九阶段 × 五引用面**:闲时 / 开局停点(地图选路停点态合并)/ 战斗中 / 结算后(胜利停点)/ 选路页 / 终局面 / 回菜单收束 / 各模态开合后(菜单域四模态)/ 两连局 + 续玩。每阶段判 20+ 取数面的存活性:`run_scope` 在树、adventure / runner / settlement 三面活死、四处回调句柄(treasure/bonus/camp/modal_flow)与 `run_scope` 成员同源。活战斗驱动复用现有 `_auto_play_round` 模式(phase/round 守卫 + `AutoPlayer.choose_dig`)。 - -### T4 渲染面内容断言三件(坏事实③) - -1. **`shot_probe.gd` 两自检**:boot 态顶层可见层 == start_overlay;菜单标题/副标题 `is_visible_in_tree` 且 `get_global_rect()` 落视口内。隔离调用改 `ProbeUiUtil.isolate_save(main, "smoke_shot_probe", false, true, true)`(refresh_resume 开——菜单截图/golden 不依赖真实档断点态)。 -2. **`shot_checker.py` 墨色判据 F**:新增 `check_text_presence()`——与中位灰度差 >60 的像素占比落在 [2%, 55%] 带(**极性无关**,不预设字色深浅)。 -3. **启动态菜单 golden**:`golden_baseline_refresh.sh` 新增 `--menu` 模式(含字体与 `button_stone.png` 素材守卫),基线 `game/tests/golden/menu_boot.png` 入库;`render_gate.sh` 补菜单 golden 逐像素对比段(基线缺失=FAIL、截图/素材缺位=SKIP,沿既有 Q5 口径)。帧差前置验证:菜单 **changed=0.0000% / max_diff=0**(光柱是静态贴片),故全屏 golden 安全、无需收窄区。 - -### T6 规范落文 + 机械面文档同步 - -- **新硬规则「验收函数无变异红记录不算验收成立」**三处落文:`CLAUDE.md` 批次工作流第 9 条(原 9–14 顺延 10–15)、`design/dev/code-conventions.md` §3.6 变异验证操作细则(注入→最窄闸见红→`git checkout` 精确还原→记录四步;变异不红的二选一处理;判据强弱分层)、req-card 技能 §7 验证闸(WorkBuddy 与 ZCode 两份副本已同步;CodeBuddy / Qoder CN 无此技能副本,不动)。 -- 机械面文档随批更新:roadmap 迭代 28 行换代+近期主战场前沿改 29+ M4;06 登记条销号改写+反哺点三条专条;07 新增 ㉗ 启动态菜单目检节;doc 三闸对基线零新增。 - ---- - -## 二、闸记录 - -| 闸 | 结果 | -|---|---| -| 冒烟全量 | **1125 / 0**(基线 1086/0,+39) | -| 单元测试 run_all | **27 套全绿** | -| probe_gate --click | **全绿**,残留 Godot = 0 | -| probe_gate --full | ⚠️ **t17_defer_probe 红**(存量红,非本批引入——详见 §六),其余五件全绿 | -| render_gate | **全绿**:shot_checker A–D 过(含新增 F 判据 I-OK×2)、棋盘 golden 0.00%×3、**菜单 golden 0.00%** | -| doc 三闸 | 对基线零新增(gdd_lint 三件 / 死链 3 / 术语 5 组,与 master 39c6544 同) | -| static_scan | S1/S2 ok、S4 ok、**S9 归零**、S10 FAIL=文件头存量 125 处(2026-10-15 新立规,清偿批在册待发令,非本批引入) | -| MC 模拟 | **零跑**(本批零数值零行为变更,装配顺序修复除外) | - -**类型闸自纠一笔**:批末 static_scan 报 S9(类型闸)**存量 1 处**——`main.gd:453` `_apply_layer_contract` 内 `var tags: Array` 未带元素类型,系本批新增代码触发(iter27 立闸时 S9 全绿)。随批修为 `Array[Variant]`,S9 归零,冒烟复跑 1125/0 不变。**这笔正是「闸不是摆设」的反面印证**:本批新增的验收函数抓别人的错,既有的类型闸同样抓本批的错。 - -**顺带清理(非本批引入,基线带入)**:`design/gdd/07-体验验证清单.md` v1.0 行处残留 `<<<<<<<` / `=======` / `>>>>>>>` 合并冲突标记(iter27-techdebt-20261014 分支合并进 master 时漏解)。两侧均有效故全留(qa 收尾批人闸核销行 + ㉖ 目检节登记行与正文节),版本号顺延 v1.1,清理注记入 v1.2 行。 - ---- - -## 三、代拍板追认单 - -> **追认结果(2026-10-17 用户令)**:第 1–13 项**全部同意,无修改意见**(含第 9–13 项五条白名单外)。第 14 项本批动作(只补 ZCode 副本、未擅自取齐)照认;其**"两副本是否取齐"仍是待裁问题**,挂在 active.md 未决面,不因本追认自动通过。 - -白名单内八项(卡片 §9)全部按授权执行;以下为实施期实际取定的形态与**白名单外需追认项**: - -| # | 事项 | 取定 | 归属 | -|---|---|---|---| -| 1 | 合同常量数据形态 | 有序 `Array[Dictionary]` + tags/host/shell 特例字段(白名单①) | 白名单 | -| 2 | 特例层断言表达 | 经宿主屏壳 / 成员间接比较(白名单②) | 白名单 | -| 3 | boot 顶层断言候选集 | 显式内容层清单(屏壳不当候选)(白名单③) | 白名单 | -| 4 | 墨色阈值 | 差 >60、占比带 [2%, 55%],按菜单文字实测定 provisional(白名单④) | 白名单 | -| 5 | 菜单 golden 收窄区 | 不收窄——帧差实证 0.0000%,直接全屏比对(白名单⑤,结论为「无需收窄」) | 白名单 | -| 6 | 变异注入手段 | 改常量序 / 插 `move_child` / 注释 `add_child` / 注释 `queue_free` / `visible=false` / 状态源取反(白名单⑥) | 白名单 | -| 7 | 新冒烟段挂载位置 | `_smoke_scene_split` → `_smoke_boot_chain` → `_smoke_run_lifecycle` → `_smoke_lifecycle_matrix`,挂 `_split_tail`(白名单⑦) | 白名单 | -| 8 | 计划书存档文件名 | `.zcode/plans/启动装配与生命周期验收补全批-loop-plan-2026-10-15.md`(白名单⑧) | 白名单 | -| 9 | **合同表规模 12 → 16 层** | 卡片基于「十二模态登记数组」,实采后扩为覆盖全视觉层的 16 层(屏壳/非视觉节点/全屏态亦入表)——约束「单点化+同源派生」未破 | **白名单外,请追认** | -| 10 | **T2 断言数 6 → 10** | 卡片写六断言,实施期把续玩钮拆出隔离三子态、补全 ConfigDB/设置/会话/浮窗门控面 | **白名单外,请追认** | -| 11 | **T3 阶段划分调整** | 卡片写「十阶段」,实施期把「地图选路停点态」并入「开局停点」(同一运行期状态,无独立断言面),得九阶段 | **白名单外,请追认** | -| 12 | **变异 2b 形态偏离计划书** | 计划书原文「注释 `_begin_session`/提前 free」;实施期取 2a=注释 `add_child`(该活不活)、2b=**注释 `queue_free`(该死不死)** 互补双向。「提前 free」改为 `free()` 会与 V3f 断言同向(仍绿),不构成有效变异,故未取 | **白名单外,请追认** | -| 13 | **07 冲突标记清理** | 基线带入的未解合并标记,本批因需同文件登记 ㉗ 而顺手解开(两侧全留,零内容发明) | **白名单外,请追认** | -| 14 | **req-card 技能双副本** | ZCode 副本与 WorkBuddy 副本已各自演进(ZCode 多两条自有条目),本批只把变异验证一条补进 ZCode 副本,**未擅自取齐**两副本差异 | 知会项;是否取齐请裁 | - ---- - -## 四、GDD 反哺点(三条,已登记 06,待用户逐点裁决另批落文) - -| # | 文档 | 反哺点 | -|---|---|---| -| 1 | `design/dev/architecture/architecture.md` | **视觉层装配合同**=`main.gd` 的 `LAYER_CONTRACT` 常量(16 层),树序=登记序=z 序同源派生,全仓唯一落位口 `_apply_layer_contract`;现行架构文档无此条款(仅 :124 提「组合根 main.gd」、:173 提「主场景装配视图单元」)——是否立条款、合同表是否随架构文档摘录待裁 | -| 2 | `design/dev/architecture/architecture.md` | **boot 链路后置条件**已由 `_smoke_boot_chain` 十断言成文;架构文档启动流程(:173)只有装配动作无后置条件——是否入册待裁 | -| 3 | `design/dev/architecture/architecture.md` | **RunScope 生命周期存活性矩阵**(九阶段×五引用面)已可执行化;架构文档 :124 只登记了 RunScope 的存在——矩阵是否入册、阶段划分是否认账待裁 | - -**与迭代 27 反哺点①的关系**:iter27 只登记了「场景分层/会话生命周期陈述滞后于实态」的方向性缺口;本批把其中「层序=谁说了算」「boot 后置条件是什么」「会话引用面何时活何时死」三件做成了代码级事实与可执行断言,本条是其**具体化承接**,落文时可合并处理。 - ---- - -## 五、变异验证记录表(六次注入,全部见红并精确还原) - -判据:**注入 → 跑最窄的那一道闸 → 见红 → `git checkout -- <文件>` 精确还原 → 复跑确认回绿**。还原后统一复跑冒烟得 **1125/0**,六轮全以 `REVERTED-CLEAN` 收尾。 - -| # | 变异点(file:line) | 注入方式 | 缺陷类 | 跑的闸 | 红输出(摘要) | -|---|---|---|---|---|---| -| 变异 1 | `game/presentation/main.gd` `LAYER_CONTRACT` 首两行 | `adventure_screen` / `menu_screen` 对调(翻装配序) | 装配序错 | `python tools/run_smoke.py` | 1125 项 **2 失败**:`V1a`(实测顶层=`@VBoxContainer@648`,菜单被冒险屏盖住)、`V1b`(菜单屏壳树序不在冒险屏壳之上)红;`V1c/V1d` 绿 | -| 变异 1b | `main.gd` `_apply_layer_contract()` 调用后 | 插入散落 `move_child(debug_overlay, 0)` | 层序硬编码(合同外落位) | 同上 | 1125 项 **2 失败**:`V1d`(函数体之外 move_child 调用点=1 应=0)、`V1c`(违例 `@Control@1057(14)≤@Control@1119(0)`)红 | -| 变异 2a | `main.gd:195` `_begin_session` | 注释 `add_child(run_scope)`(会话对象不挂树) | 对象该活不活 | 同上 | 1125 项 **22 失败**:`V2e` 红 + V3 全部 21 个阶段面「run_scope=不在树」 | -| 变异 2b | `main.gd:191-192` `_begin_session` | 注释 `run_scope.queue_free()`(旧会话不销毁) | 对象该死不死 | 同上 | 1125 项 **1 失败**:`V3f`「收束后旧局经 queue_free 消亡(is_instance_valid=false)」红 | -| 变异 3 | `main.gd:218` `_ready` | `_start_overlay.visible = false`(藏菜单层) | 层被盖/不可见 | 冒烟 + 窗口化 `shot_probe` + `golden_compare` + `shot_checker` | 冒烟 **3 失败**(`V1a`/`V2c`/`V3a`);探针自检 **3 问题**(顶层≠start_overlay、标题/副标题 `is_visible_in_tree=false`);golden `changed=34.23%` FAIL;`shot_checker` exit=1 | -| 变异 4 | `main.gd:531` `_refresh_resume_button` | `_resume_btn.visible = not has`(状态源倒置) | 状态源/时序倒置 | `python tools/run_smoke.py` | 1125 项 **6 失败**:`V2d` 四条全红(boot 态、无断点态、有断点态、清断点回隐)+ `V3a` + `V3i` | - -### ⚠️ 变异 3 暴露的一条判据边界(重要,如实记录) - -**F 判据(墨色占比)本身没有红**——菜单层被藏后,底层棋盘内容透过标题框仍给出 33.48% 的高反差像素,落在 [2%, 55%] 带内,`I-OK` 照过。真正拦下这个缺陷的是另外两件:探针的 `is_visible_in_tree` 自检,和 golden 逐像素(34.23%)。`shot_checker` 虽 exit=1,但红的是 **C 判据**(背景纹理幅度 79.4 > 18),属间接命中。 - -**结论**:F 判据只能证伪「整框空白/整框糊」,**不证明「框里是菜单标题」**。菜单内容断言的强判据是「可见性自检 + golden 逐像素」,F 判据为补充。这条边界已同步写进 `code-conventions.md` §3.6 的「判据强弱分层」,供后续写卡配判据时援引。 - ---- - -## 六、残留与去向 - -### 6.1 probe_gate --full 的 t17_defer_probe 红(存量红,**非本批引入**,待裁) - -**① 现象**:`tools/probe_gate.sh --full` 中 `t17_defer_probe` 失败——`[t17_defer] FAIL — 关卡画面未出现`(exit=2;首次运行时表现为 exit=124 超时挂死,同一根因的两种表现)。`--full` 的其余五件(ui_input / ui_struct / ui_contrast / ui_probe / ui_tune / fx)**全绿**,`--click` 亦全绿。 - -**② 证据链(三条,均指向「非本批引入」)**: - -| 证据 | 结果 | -|---|---| -| 主区 master 39c6544(**不含本批任何改动**)跑同一探针 | **同样 FAIL 4/4**,失败行与本批完全一致 | -| 把真实档 `user://save.json` 临时改名移开后跑同一探针 | **PASS**(exit=0,15s,`胜利同帧挂起+排播完开窗 两断言全过`) | -| 探针自身行为 | 首次跑绿、跑完即把真实档写成带断点状态,其后必红——**探针会污染它本应隔离的真实档** | - -**③ 机理**:`_start_adventure_from_menu()`(`main.gd:498`)在 `save_manager.has_breakpoint()` 为真时不开冒险,改弹「已有未完冒险」确认框。真实 `user://save.json` 当前存在未完冒险断点时,探针的隔离(`main.save_manager = iso_c`)没能覆盖到这条路径,于是 60 帧内等不到 `level_screen.visible` → FAIL。 - -**④ 补充事实(须告知)**:`user://` 目录(`%APPDATA%/Godot/app_userdata/DungeonSweeperVerticalSlice/`)由**全部 worktree 共享**(同 project name),所以主区与任何 worktree 的探针/冒烟都在读写同一份存档。本机这份真实档现在带有一个未完冒险断点。**本批验证过程中曾为定位根因临时改名移开该档,已按原样还原并通过逐字节 `cmp` 校验一致**(备份留 `/d/tmp_save_backup_20261015.json`)。 - -**⑤ 历史沿革**:iter26 台账记「probe click/full 全绿」,**iter27 台账只记了 `probe click` 未记 `--full`** —— 该红大概率自 iter27(row_pacer 排播泵迁出 + ModalFlow 抽取)起就存在而未被跑到。probe_gate 头注亦有预言:「超时多半=探针未适配新停点层,归 probe 适配批」。 - -**⑥ 待裁(不擅自处理)**:本红属**探针适配存量债**,修它=改探针隔离方式,是卡片外的新需求。三个选项请裁: - -- **甲**:认可存量红、照常合并——红与本批无关,master 现状同红,合并不会使任何东西变差; -- **乙**:先修探针隔离(补真实档隔离/跑前清断点)再合并——属新需求,需用户批后另起小批; -- **丙**:用户先自行处置本机真实档断点(游戏内开新冒险覆盖或删档),我再复跑 `--full` 取绿后合并——但此法只治本机这一次,探针自污染的根因仍在。 - -### 6.2 实机目检(登记不阻塞,2026-10-12 立规) - -已登记 `design/gdd/07-体验验证清单.md` **㉗ 启动态菜单目检**五观测项:启动即见主菜单 / 菜单六钮可点 / 菜单与战斗互不遮挡 / 各覆盖层开合层级正确 / 音量与减动效启动即生效。**登记完毕即批内义务了结**,用户自行安排时间验收。 - -### 6.3 其他 - -- 计划书存档:`.zcode/plans/启动装配与生命周期验收补全批-loop-plan-2026-10-15.md`(不入 git)。 -- 需求卡片按「中间产物吸收即死」惯例不入 git;卡片所记基线 1081 与实测 1086 的差异已随本批回写 roadmap 与 06。 -- req-card 技能两份副本(WorkBuddy / ZCode)本批各补一条后**仍有两条 ZCode 自有条目未取齐**,是否取齐请裁(§三 #14)。 - ---- - -## 七、冒烟断言数增量呈报 - -**1086 → 1125,净 +39**,逐项可溯源: - -| 项 | 条数 | -|---|---| -| 新增 V1(装配合同四断言:V1a/V1b/V1c/V1d) | +4 | -| 新增 V2(boot 链路十断言) | +10 | -| 新增 V3(生命周期矩阵,九阶段面 + 各附加判据) | +28 | -| 退役裸下标断言(`kids.find(...)` 三处——合同链断言已覆盖) | −3 | -| **合计** | **+39** | - -(新增 42 条全部带 `〔装配生命批 Vn〕` 尾缀,可与需求卡片 §7 逐条 grep 对账。) diff --git a/roadmap.md b/roadmap.md index 639fee5b..6504b50b 100644 --- a/roadmap.md +++ b/roadmap.md @@ -61,7 +61,7 @@ | 迭代 25 | 已完成(2026-10-13) | 已退役(git 历史可考) | 2026-10-13 | — | 已退役(git 历史可考) | | 迭代 26 | 已完成(2026-10-14) | 已退役(git 历史可考) | 2026-10-14 | — | 已退役(git 历史可考) | | 迭代 27 | 已完成(2026-10-14) | 已退役(git 历史可考) | 2026-10-14 | — | 已退役(git 历史可考) | -| 迭代 28 | 已完成(2026-10-15) | 已退役(git 历史可考) | 2026-10-15 | — | reports/iter28-实现报告-2026-10-15.md | +| 迭代 28 | 已完成(2026-10-15) | 已退役(git 历史可考) | 2026-10-15 | — | 已退役(git 历史可考) | | 迭代 29 | 已完成(2026-10-16) | 已退役(git 历史可考) | 2026-10-16 | — | reports/iter29-实现报告-2026-10-16.md | | 迭代 30 | 已完成(2026-10-17) | 已退役(git 历史可考) | 2026-10-16 | — | reports/iter30-实现报告-2026-10-17.md | | 迭代 31 | 待开工 | reports/需求卡片-代码术语刷新批-2026-10-18.md、reports/需求卡片-凭证件裁削批-2026-10-18.md | 2026-10-18 | ≈1.5 周 | — | From 487c2072f10c92054ef52f54bcf728762ad6bd41 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 15:03:26 +0800 Subject: [PATCH 13/59] =?UTF-8?q?chore(=E6=89=B9=E5=90=8E=E6=94=B6?= =?UTF-8?q?=E5=B0=BE):=20=E8=BF=AD=E4=BB=A3=2029=20=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E6=8A=A5=E5=91=8A=E9=80=80=E5=BD=B9=E2=80=94=E2=80=94=E5=90=B8?= =?UTF-8?q?=E6=94=B6=E5=8D=B3=E6=AD=BB=E5=88=A0=E9=99=A4=EF=BC=88=E5=8F=8D?= =?UTF-8?q?=E5=93=BA=E7=82=B9=E4=B8=89=E6=9D=A1=E5=B7=B2=E8=90=BD=E6=96=87?= =?UTF-8?q?=20test-conventions=20=C2=A77/=C2=A78=20=E4=B8=8E=2007=20?= =?UTF-8?q?=E3=89=96=20=E6=9C=BA=E6=A3=80=E6=89=BF=E6=8E=A5=E6=B3=A8?= =?UTF-8?q?=E8=AE=B0=E3=80=8112=20=E9=A1=B9=E4=BB=A3=E6=8B=8D=E6=9D=BF?= =?UTF-8?q?=E5=B7=B2=E8=BF=BD=E8=AE=A4=E3=80=81=E6=B5=8B=E8=AF=95=E5=9F=9F?= =?UTF-8?q?=E9=81=97=E7=95=99=E4=B8=83=E9=A1=B9=E5=9C=A8=E5=86=8C=2006?= =?UTF-8?q?=E3=80=81=C2=A7=E5=85=AD.1=20parity=20=E5=BE=85=E6=89=B9?= =?UTF-8?q?=E5=87=86=E4=BA=8B=E9=A1=B9=E6=8C=89=E3=80=8CMC=20=E6=97=A0?= =?UTF-8?q?=E6=95=B0=E5=80=BC=E6=94=B9=E5=8A=A8=E9=9B=B6=E8=B7=91=E3=80=8D?= =?UTF-8?q?=E7=BA=A2=E7=BA=BF=E5=88=A4=E9=97=AD=E5=90=88=EF=BC=9A=E6=9C=AC?= =?UTF-8?q?=E6=89=B9=E5=AF=B9=20battle=5Forchestrator.gd=20=E4=BB=85?= =?UTF-8?q?=E5=8A=A0=E6=96=AD=E8=A8=80=E8=B1=81=E5=85=8D=E5=B8=B8=E9=87=8F?= =?UTF-8?q?=E3=80=81=E9=9B=B6=E6=95=B0=E5=80=BC=E6=94=B9=E5=8A=A8=EF=BC=8C?= =?UTF-8?q?=E4=B8=8D=E8=A1=A5=E8=B7=91=EF=BC=8C=E7=90=86=E7=94=B1=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=A3=81=202026-10-20=EF=BC=89=EF=BC=9B=E6=9C=AC?= =?UTF-8?q?=E6=89=B9=E6=97=A0=E5=AE=9E=E6=9C=BA=E7=9B=AE=E6=A3=80=E9=A1=B9?= =?UTF-8?q?=E3=80=8107=20=E6=97=A0=E6=96=B0=E5=A2=9E=EF=BC=9Broadmap=20?= =?UTF-8?q?=E8=BF=AD=E4=BB=A3=2029=20=E8=A1=8C=E5=AE=9E=E7=8E=B0=E6=8A=A5?= =?UTF-8?q?=E5=91=8A=E5=88=97=E6=94=B9=E9=80=80=E5=BD=B9=E4=BF=9D=E7=95=99?= =?UTF-8?q?=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- reports/iter29-实现报告-2026-10-16.md | 169 -------------------------- roadmap.md | 2 +- 2 files changed, 1 insertion(+), 170 deletions(-) delete mode 100644 reports/iter29-实现报告-2026-10-16.md diff --git a/reports/iter29-实现报告-2026-10-16.md b/reports/iter29-实现报告-2026-10-16.md deleted file mode 100644 index 180caba0..00000000 --- a/reports/iter29-实现报告-2026-10-16.md +++ /dev/null @@ -1,169 +0,0 @@ -# 迭代 29 实现报告 · 测试分层与门禁语义修正批(2026-10-16) - -- 需求卡片:已退役(git 历史可考)——原「测试分层与门禁语义修正批」**v2.0**,三轮复查定稿、零待裁点 -- 开工门 U0:用户 `/iter 29` 发令(2026-10-16)。基线 master `752c9a0a` -- worktree:`g-plan2-iter29-testlayers`,分支 `iter29-testlayers-20261016`,八提交(`698d864d` … `c3b64030`) -- 用户原始诉求(本批要兑现的三条):①最单元的逻辑代码有它的单元测试;②整体的模块有它的接口测试; - ③整体的系统在执行之后,也有它 UI 方面的和场景切换相关的测试。**并且验收不能只是"冒烟"—— - 可以是冒烟,但更重要的是逻辑正确性** - ---- - -## 一、批次概览 - -| 卡 | 内容 | 状态 | -|---|---|---| -| T0 | 证据坐实与基线冻结(三反例实测 + 墙钟 + 行号复核 + 存量红留档) | ✅ | -| T1 | 本地闸判定三硬闸(退出码/脚本错误扫描/断言数下限) | ✅ | -| T2 | 术语订正 + CI 残留清除(机械面) | ✅ | -| T3 | L2 接口层建承载(`integration/` + parity 条件闸件收编) | ✅ | -| T4 | L3 屏壳切换探针 `screen_flow_probe`(入轻闸默认段) | ✅ | -| T5 | L1 覆盖补洞(4 个 core + 呈现层两件) | ✅ | -| T6 | 扫描域:S3 路径修正 + 零命中自检 + 补 S5 | ✅ | -| T7 | 游离脚本台账 + golden 时效判定 | ✅ | -| T8 | 文档同步闸(架构事实源回写 + 06 登记)与全闸 | ✅ | - -**读数**:冒烟 **1127/0**(与开工日持平,本批零新增冒烟断言);单元套件 **27 → 33 套**; -在闸探针 **9 → 10 件**(新增 `screen_flow_probe`);轻闸 `--quick` 墙钟 363s → 405s; -全量重闸 **exit=0,存量红零新增**。 - ---- - -## 二、四件事的交付 - -### ① 本地闸三硬闸(本批改造成效最大的一卡) - -判定语义从「超时 + 日志含 PASS 串」扭到三硬闸,**每一条都有反例实证**(不是推断,是跑出来的): - -| 硬闸 | 反例构造 | 改前判定 | 改后判定 | -|---|---|---|---| -| 退出码为唯一权威判据 | 探针打印 PASS 后 `quit(1)` | `[probe_gate] 全绿` ❌ | `FAIL — 退出码=1(PASS 串不抵)` ✅ | -| 脚本错误扫描命中即红 | 套件中途触发 `SCRIPT ERROR` 后仍退出 0 | `[run_all] PASS` ❌ | `FAIL — 输出含脚本错误标记` ✅ | -| 断言数为零即红 | `Kit.finish()` 时 `checks==0` | `all green (0 checks)` ❌ | 返回专用退出码 **2** → `FAIL` ✅ | - -实现要点: -- `probe_gate.sh` 八件探针判定统一走 `verdict` 函数(退出码优先 → 脚本错误扫描 → 签名标记附加判据); - `ui_click_probe` 本就走退出码语义、日志不写 PASS,签名标记传它自己的 `click_probe` 串,不强加。 -- 新闸件 `tools/error_scan.py`:错误标记 `import` 自 `run_smoke.py` 的 `ERROR_MARKERS`,**禁第二份清单**。 -- `run_all.gd` 侧遇到两个本机事实(都写进注释防复发): - ① `OS.execute` 的输出管道在本机恒空(实测 0 行)——子套件输出必须交给系统命令解释器重定向落盘再读; - ② `OS.get_executable_path()` 返回的是 GUI 子系统 exe,它起的子进程 stdout/stderr 句柄无效—— - 必须换 `*_console.exe`(`GODOT_BIN` 优先)。 -- 断言下限用**专用退出码 2**(不是 1):致命类套件 manifest 期望 1,零断言若也返回 1 会被 expect 协议放过。 - -### ② L2 接口层从零建承载 - -- 建 `game/tests/integration/`,首个集成用例 `save_rng_roundtrip_test.gd`(17 条断言):存档 ⇄ RNG 快照往返, - 跨 SaveManager(落盘 + 版本迁移链)× AdventureRunner(断点消费)× RngService(续跑零跳号)× 停点态确定性。 - 与 `unit/core/breakpoint_resume_test` 的分工:那件是单测只验首战开板一致,本件验跨系统闭环, - 含**「旧版本档经迁移链后断点仍可续玩」**这条真实玩家路径。 -- `tools/parity_anchor.py` 收编为重闸 **11 号条件闸件**:每次跑批都对 merge-base 做一遍触面判定 - (`data/tables`/`rng_service`/`save_manager`/`meta_progression`/`settlement`/`damage_math`/ - `damage_controller`/`battle_orchestrator`/`adventure_monte_carlo`),未触面 SKIP;**触面也不自动跑**—— - 它调的是 MC 脚本,属「跑批发起前须用户批准」红线,闸只负责把触面判定做一遍并显式要求批准 - (批准后 `PARITY_APPROVED=1` 重跑)。**本批即判为触面(改了 `battle_orchestrator.gd`),故挂在 NEED-APPROVAL 待你批准**(见第六节)。 - -### ③ L3 屏壳切换探针 - -新建 `game/smoke/screen_flow_probe.gd/.tscn`:走 菜单→营地→菜单→冒险→(关卡屏⇄战斗屏)→放弃→终局→菜单 -六步主流程与两条回退路径,每步断言屏级互斥 + 流程状态位,入**轻闸默认段**。全库 `change_scene` 零命中、 -屏切换全靠 visible 互斥,这正是最容易被装配顺序改动悄悄破坏又最难被单测覆盖的面。 - -判据两处订正(首跑实测抓出):① 屏标记不能裸看 `visible`——战斗容器 `battle_root` 在局外也 visible, -会把 boot 态误判成「菜单与冒险同时在场」;② 互斥不能用「可见屏计数 ≤1」——终局覆盖层合法叠在冒险内容之上 -(终局态 `is_adventure` 尚未收束,是设计如此),改为冲突对判定,合法叠加仅「终局+冒险」这一对。 - -### ④ L1 补洞 + 术语订正 + 台账清理 - -- 新增六套(全部进 manifest):`board_generator`(9 条)/`minesweeper_rules`(12 条)/ - `config_db_resolver`(8 条)/`config_db_cross_validator`(4 条)/`hud_presenter`(5 条)/`battle_narrator`(9 条)。 - 三屏壳的断言面由 ③ 的探针承担,不另起第二载体。 -- 术语:「冒烟」回归本义=秒级存活检查,写进 README 术语小节,并显式点破两处历史遗留命名 - (`run_smoke.py` 与 `game/smoke/` 名带 smoke,实际承载的是系统级断言面与场景探针——判定看语义不看文件名)。 -- 台账:`game/smoke/` 15 个不带 `.tscn`、不入闸的手动入口件逐个定性成表(用途 + 触发方式 + 结果由谁判), - 存疑一律按在役登记并标注,禁「没看见=死件」式清理。 -- golden:**先判再动**——实测棋盘三图 changed 0.00%/0.00%/0.00%、菜单 0.15%,均远低于 2% 阈值 ⇒ 判有效, - 留在位不重制(禁「重制一下就绿了」掩盖真实视觉回归)。 - ---- - -## 三、代拍板追认单(超清单必呈报;本批共 12 项) - -> **追认结果(2026-10-17 用户令)**:以下十二项**全部同意,无修改意见**。第四节「经你裁决的四项」是施工中已问过、你已答的四条,不在本追认范围,维持原记录。 - -| # | 代拍板事项 | 处置与依据 | -|---|---|---| -| 1 | 三硬闸的具体实现写法 | `probe_gate` 抽 `verdict` 函数;错误扫描抽独立闸件 `tools/error_scan.py`(标记 import 自 `run_smoke.py`) | -| 2 | 断言数下限的阈值 | 每套件 ≥1(防误伤小套件);零断言用专用退出码 2 与「断言失败=1」区分 | -| 3 | `integration/` 内部目录分类 | 平铺,按系统命名(`save_rng_roundtrip_test.gd`)——首例而已,够用不加层 | -| 4 | 新集成套并入 `run_all` manifest 的执行细节 | 零新机制,与单元套件同一入口同一协议 | -| 5 | 新单测/新探针的文件命名与落点 | 沿用 `[system]_[feature]_test.gd` 与 `presentation/` 归位 | -| 6 | 4 个 core 模块单测的断言面取舍 | 各 4–12 条真值断言,期望值一律由盘上/注入内容数出来(零玩法数值字面量) | -| 7 | **断言本身写错且与现行设计冲突**时的修法(契约 1 唯一例外) | 见第四节「经你裁决的四项」,逐条列明 | -| 8 | 游离脚本「在役/失效」的判定 | 存疑按在役登记并标注;`CLAUDE.md` 在册入口禁当死件 | -| 9 | S5 规则的正反例构造 | 形态=标识符后紧跟 `.` 的成员访问,排除注释行与字符串字面量;core 实测零命中 | -| 10 | 提交切分与分支命名 | 八提交按 T0–T8 一卡一笔;分支 `iter29-testlayers-20261016` | -| 11 | **S3 零命中自检的实现形态** | 扫描路径收为单点变量 + 规则自己数扫描面文件数,为零即判红,且规则体包进自检成立分支 | -| 12 | **条件闸件的 diff 触面路径表** | 写进 `run_all_gates.sh` 内(不自造第二份清单),见上文 ② | - ---- - -## 四、经你裁决的四项(施工中冒出的分歧,未自答) - -1. **`fx_grant_gp` 补进行来源断言豁免表**(你裁「本批补豁免」):`grant_segment.gd:221` 发「专长·GP 入账」 - 效果行(source_class=`fx_grant_gp`、origin_cell=(-1,-1)),而 `SOURCE_EXEMPT_CLASSES` 只豁免了 `fx_reveal` - ⇒ 每局触发行来源断言失败 7 次,因脚本错误不改退出码被闸长期漏过。改动=一行常量加一个字符串, - 零玩法行为变更(迭代 21 同款修过 `fx_reveal`,本例是同一张表的漏网)。 -2. **manifest 增 `negative` 字段**(负面套件豁免错误扫描一闸):仅 `reward_dangling_treasure` 一件—— - 坏表是它的测试目标,输出里的 Parse Error 属误伤。退出码与断言下限照判,不是开后门。 -3. **`config_db_test` 的 10 条被吞断言**(你裁「本批全修」):`rows` 是 `Array[Dictionary]` 定型属性, - 直接赋 untyped 数组字面量触发 `Invalid assignment` ⇒ **中断整个函数**,敌人表「行集构成三条纪律」 - 的 10 条断言从未执行过(文件 31 处 check,实跑 21 条)。改 `rows.assign([...])` 后 26 条全跑, - 其中两条正向断言见红,根因是**夹具缺 depth-0 锚行**(`validate` 的 anchor 规则),补锚行后全绿。 -4. **`system_contracts_test` 的空桩换真实实例**(同上):`RngStub`/`UnitContainerStub` 赋给定型成员 - 报 `Trying to assign value of type ''`,`RngStub` 类删除,`UnitContainer`/`StatusContainer` 改真实实例。 - ---- - -## 五、闸与读数(全量重闸 `tools/run_all_gates.sh`,commit `c3b64030`) - -| 闸 | exit | 说明 | -|---|---|---| -| 01 冒烟全量 | 0 | **1127 项检查 0 项失败**(与开工日持平) | -| 02 单元套件 | 0 | **33 套**(26 单元 + 1 集成 + 6 新单测);编排层另扫 `unit.log` 零命中 | -| 03 探针 --click | 0 | 五件(含新增 screen_flow)全绿,残留 Godot=0 | -| 04 探针 --full | 0 | 四件全绿 | -| 05 渲染闸 | 0 | shot_checker 全过;棋盘 golden 三图 0.00%;菜单 0.15%(≤2%) | -| 06 gdd_lint / 07 doc_link / 08 doc_term | 0 | doc_term 首跑抓到我新写的退役词「对拍」1 处,已改正 | -| 08b active.md 体量 | 0 | — | -| 09 静态扫描 | 1 | **存量红零新增**:S10 文件头存量 127 处,指纹与基线 `4354b2aa72a7` 一致 | -| 10 熵增闸 | 0 | — | -| 11 回放确定性对拍 | NEED-APPROVAL | 本批 diff 触及结算面,对拍需你批准发起(见第六节) | - -**验收通过**(`all_green=true`,存量红零新增)。轻闸 `--quick` 墙钟 405s(开工日 363s + 新探针约 40s)。 - ---- - -## 六、待裁与遗留 - -0. **【合回状态:已合并进 master(`fff4f120`,十提交,2026-10-16)】** 本项原文为「暂不合回,等两个非本批红处理完」 - (2026-10-16 用户裁),两个红其后各自结案:①渲染闸 `menu_boot.png` changed=4.61%(菜单 golden 热区漂移) - ——基线已在合并代码上显式重采(`dac9a94b`),现行菜单与棋盘三张 golden 均 0.00%;②gdd_lint - `01-核心循环.md` R5 缺流程图——由引入批补流程图结案(提交 `fcb8c3f8`+`8c18b52b`),基线 06 已回绿。 - 本段为 2026-10-17 迁位批(`design/qa/` → `reports/`)改写,原待裁文字 git 历史可考。 - -1. **11 号闸的 parity 对拍要不要跑一次**(需你批准,我不能自行发起):触面判定是机械的路径匹配, - 本批对 `battle_orchestrator.gd` 的改动实际只是加一个断言豁免常量(零玩法行为变更、零数值改动)。 - - 若按「MC 无数值改动零跑」红线 ⇒ 不跑,闸维持 NEED-APPROVAL(回执里留名,不判失败); - - 若要验证一次 ⇒ 批准后 `PARITY_APPROVED=1 tools/run_all_gates.sh`(三变体约 10–15 分钟)。 -2. **GDD 反哺点三条**(2026-10-17 用户逐条裁决:三条全部写入): - - 「三硬闸」与「新写测试件全类型标注」→ **test-conventions.md §7**(code-conventions §3 已独立成文至此,故落此处); - - 「判定可靠性优先于覆盖率」→ **test-conventions.md §8**(本批核心命题成节); - - `screen_flow_probe` 转机检 → **07 v1.4**:㉖① 保留不注销,节首加机检承接注记。 - 本条补登记为 06 专条(原漏登)。 -3. **06 已登记本批未收的七项**(不阻塞不排期):余下 3 个 core 零指名模块、`render_gate` 的脚本错误扫描缺失、 - S7/S8(S6 亦仍在 TODO)、E 级卫生件、行覆盖率度量、`smoke_all` 拆分、parity 触面判定偏粗。 -4. **本批最有价值的副产品**(2026-10-17 用户裁决:写入):脚本错误会**静默中断所在函数的剩余断言**而 - 套件仍报「全绿」——本批至少三处实证(敌人表行集纪律 10 条零覆盖、`Callable` 形参类型写错让解析函数 - 返回 null)。已由三硬闸之二机制性拦住;机制事实与「写验收函数须自证断言全数执行」义务已写入 - **test-conventions.md §8**。 diff --git a/roadmap.md b/roadmap.md index 6504b50b..76be4d80 100644 --- a/roadmap.md +++ b/roadmap.md @@ -62,7 +62,7 @@ | 迭代 26 | 已完成(2026-10-14) | 已退役(git 历史可考) | 2026-10-14 | — | 已退役(git 历史可考) | | 迭代 27 | 已完成(2026-10-14) | 已退役(git 历史可考) | 2026-10-14 | — | 已退役(git 历史可考) | | 迭代 28 | 已完成(2026-10-15) | 已退役(git 历史可考) | 2026-10-15 | — | 已退役(git 历史可考) | -| 迭代 29 | 已完成(2026-10-16) | 已退役(git 历史可考) | 2026-10-16 | — | reports/iter29-实现报告-2026-10-16.md | +| 迭代 29 | 已完成(2026-10-16) | 已退役(git 历史可考) | 2026-10-16 | — | 已退役(git 历史可考) | | 迭代 30 | 已完成(2026-10-17) | 已退役(git 历史可考) | 2026-10-16 | — | reports/iter30-实现报告-2026-10-17.md | | 迭代 31 | 待开工 | reports/需求卡片-代码术语刷新批-2026-10-18.md、reports/需求卡片-凭证件裁削批-2026-10-18.md | 2026-10-18 | ≈1.5 周 | — | From 893aac795ffd391610b2a89142cb0fa1276328cd Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 15:08:18 +0800 Subject: [PATCH 14/59] =?UTF-8?q?chore(=E6=89=B9=E5=90=8E=E6=94=B6?= =?UTF-8?q?=E5=B0=BE):=20=E8=BF=AD=E4=BB=A3=2030=20=E4=BA=A7=E5=87=BA?= =?UTF-8?q?=E7=89=A9=E9=80=80=E5=BD=B9=E2=80=94=E2=80=94=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E6=8A=A5=E5=91=8A/=E4=BB=A3=E6=8B=8D=E6=9D=BF=E8=BF=BD?= =?UTF-8?q?=E8=AE=A4=E5=8D=95/=E5=8F=8D=E5=93=BA=E7=82=B9=E6=B8=85?= =?UTF-8?q?=E5=8D=95=E4=B8=89=E4=BB=BD=E6=8C=89=E5=90=B8=E6=94=B6=E5=8D=B3?= =?UTF-8?q?=E6=AD=BB=E5=88=A0=E9=99=A4=EF=BC=88=E5=8F=8D=E5=93=BA=E7=82=B9?= =?UTF-8?q?=E4=B8=83=E6=9D=A1=E5=B7=B2=E4=BA=8E=202026-10-17=20=E5=85=A8?= =?UTF-8?q?=E9=83=A8=E5=9B=9E=E5=86=99=E5=B9=B6=E5=A4=8D=E6=A0=B8=E8=90=BD?= =?UTF-8?q?=E6=96=87=E3=80=817=20=E9=A1=B9=E4=BB=A3=E6=8B=8D=E6=9D=BF?= =?UTF-8?q?=E5=B7=B2=E8=BF=BD=E8=AE=A4=E3=80=8107=20=E3=89=98=20=E4=BA=94?= =?UTF-8?q?=E9=A1=B9=E5=AE=9E=E6=9C=BA=E7=9B=AE=E6=A3=80=E5=9C=A8=E5=86=8C?= =?UTF-8?q?=E3=80=81.uid=20=E5=8D=AB=E7=94=9F=E7=BC=BA=E5=8F=A3=E5=B7=B2?= =?UTF-8?q?=E9=9A=8F=E5=90=8E=E7=BB=AD=E6=89=B9=E9=97=AD=E5=90=88=EF=BC=89?= =?UTF-8?q?=EF=BC=9B=E6=8A=A5=E5=91=8A=20=C2=A7=E5=85=AD-1=20=E9=98=94?= =?UTF-8?q?=E8=A7=86=E9=87=8E=E5=B8=A6=E8=A1=A8=E8=BF=B0=E5=86=B2=E7=AA=81?= =?UTF-8?q?=E8=BF=81=2006=20=E6=96=B0=E6=9D=A1=EF=BC=88=E7=A7=98=E5=AE=9D?= =?UTF-8?q?=E8=A1=A8=E4=B8=8E=20treasure=5Fitems.tres=20desc=20=E4=BB=8D?= =?UTF-8?q?=E5=86=99=E3=80=8C=E7=B1=BB=E5=9E=8B=E5=BE=AE=E5=85=89=208?= =?UTF-8?q?=E2=86=9212=20=E6=A0=BC=E3=80=8D=EF=BC=8C=E4=B8=8E=20HUD?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E3=80=8C=E5=BE=AE=E5=85=89=E4=B8=8D=E9=9A=8F?= =?UTF-8?q?=E8=A7=86=E9=87=8E=E6=89=A9=E3=80=8D=E5=86=B2=E7=AA=81=EF=BC=8C?= =?UTF-8?q?=E5=BE=85=E6=95=B0=E6=8D=AE=E6=96=87=E6=9C=AC=E8=AE=A2=E6=AD=A3?= =?UTF-8?q?=EF=BC=89=EF=BC=9B=E5=AD=98=E6=A1=A3=E5=88=B6=E5=8D=A1=E7=89=87?= =?UTF-8?q?=20F8=20=E7=9A=84=E5=9F=BA=E7=BA=BF=E8=AF=BB=E6=95=B0=E6=8C=87?= =?UTF-8?q?=E8=B7=AF=E6=94=B9=E5=86=85=E8=81=94=EF=BC=8Bcommit=207ffd1dc0?= =?UTF-8?q?=EF=BC=9Broadmap=20=E8=BF=AD=E4=BB=A3=2030=20=E8=A1=8C=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E6=8A=A5=E5=91=8A=E5=88=97=E6=94=B9=E9=80=80=E5=BD=B9?= =?UTF-8?q?=E4=BF=9D=E7=95=99=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/gdd/06-待办清单.md | 8 ++ reports/iter30-代拍板追认单-2026-10-17.md | 19 ---- reports/iter30-反哺点-2026-10-17.md | 31 ------- reports/iter30-实现报告-2026-10-17.md | 92 ------------------- .../需求卡片-存档制数据层改造批-2026-10-18.md | 2 +- roadmap.md | 2 +- 6 files changed, 10 insertions(+), 144 deletions(-) delete mode 100644 reports/iter30-代拍板追认单-2026-10-17.md delete mode 100644 reports/iter30-反哺点-2026-10-17.md delete mode 100644 reports/iter30-实现报告-2026-10-17.md diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index de5f2bc8..532eae41 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -311,6 +311,14 @@ **状态**:待写卡 +#### 阔视野带效果表述与类型微光口径冲突(2026-10-20 登记,来源=批次移交,设计面=工程直入) + +**现状**:迭代 30 卡①实现报告登记的存量冲突(报告随批后收尾退役,git 历史可考):[秘宝](systems/跨局循环/秘宝.md) 普通档表「阔视野带」行一句话写作「类型微光范围 8 格→12 格」,`game/data/tables/treasure_items.tres` 该行 `desc` 同口径;但 [HUD框架](systems/表现与支撑/HUD框架.md) 迷雾节配套拍板已定「类型微光不随视野扩大(贴身 8 格、微光锚=可挖域)」,实现面微光作用集恒为 `_diggable` 子集,该件实际效果是 `light_radius_bonus` 扩灯光区(迷雾视野 8→12),不扩类型微光。两处表述属提灯功能承接时期的遗留措辞。 + +**归属**:秘宝.md 普通档表该行 + treasure_items.tres 该行 desc(数据文本订正批;只改文字、不改机制) + +**状态**:待写卡(备选) + #### 第二 / 三关棋盘观感——亮度与对比度(2026-10-13 登记,来源=playnote,设计面=双轨) **现状**:来源=playnote 用户试玩记录「UI 优化,第二第三关的棋盘看着太累了;不知道是因为亮度还是对比度的原因,看着非常费劲,非常不舒服」。2026-10-13 用户裁定:**这是需要做的**,且本就属版本标准的覆盖范围——[08-Alpha版本标准](08-Alpha版本标准.md)「五 · 表现」已新增「棋盘观感(第二 / 三关亮度与对比度)」行,标待做。**开工前须先定性(沿用既有裁决)**:是**素材轴**问题(棋盘瓦片与格面图标本身的明度与色相),还是 **UI 轴**问题(舞台底色与叠加层的对比关系)——两轴修法完全不同,定性错了等于白改一轮;该定性要求(原备忘 (e) 项)是本条的开工前置。2026-10-16 曾编入迭代 30 卡③(UI 呈现三卡批序位③),2026-10-17 用户裁定剔除回待设计(自身挂「素材轴/UI 轴」定性人闸+甲/乙〔recolor/远程生图重产〕素材裁点;若裁乙,其瓦片规格依赖战斗一屏样张批的目标规格清单产出)。v1.4 旧卡留 reports/需求卡片-二三关棋盘观感批-2026-10-16.md 作素材,非已写卡状态。与已完成注销的「呈现层残余 <4.5:1 文字位」分工:本条管**棋盘区域整体的观感**(亮度/对比度/费劲感,体感问题),彼条管**具体文字位的对比度读数**(机检可判硬指标),两条不同面不互相替代。 diff --git a/reports/iter30-代拍板追认单-2026-10-17.md b/reports/iter30-代拍板追认单-2026-10-17.md deleted file mode 100644 index f27a50e5..00000000 --- a/reports/iter30-代拍板追认单-2026-10-17.md +++ /dev/null @@ -1,19 +0,0 @@ -# 迭代 30 卡① 未开格类型徽章批 · 代拍板追认单 - -- 批次:迭代 30 卡①(分支 `iter30-glow-20261017`,worktree `g-plan2-iter30-glow`) -- 依据:卡片 §9 代拍板白名单(超清单必呈报);Q1–Q5 本体不在白名单(v1.2 已裁,见 §10 裁定行,本批未开放重裁) -- 完成日 2026-10-17。以下 7 项为批内代拍板决定,逐项留痕待追认或推翻 - -| # | 白名单项 | 批内决定 | 理由/备注 | -|---|---|---|---| -| 1 | 新常量与函数命名、文件落点 | 色板与归组落 `ui_kit.gd` 单点:组号常量 `GLOW_NONE/BUFF/HEAL/PIERCE/MAGIC/AOE`、五组色值 `TG_GLOW_BUFF/HEAL/PIERCE/MAGIC/AOE`、呈现参数 `TYPE_GLOW_ALPHA/BAND_FRAC/SOFT/CORNER`;函数 `glow_group_for_cell_type()`(九值封闭)+`glow_color_for_group()`(组号→色值,透明出口)。绘制面新建单点件 `cell_type_glow.gdshader`(canvas_item 距离场)+`cell_type_glow_layer.gd`(承载/注参),不塞进 `board_cell_unit.gd` | 守卫「新增色值一律入 ui_kit 单点、呈现层裸 Color8 = 0」可机检(静态段既有);shader 与承载件分离 = uniform 参数表可直读可断言。与既有 TG_* 卡顶带**两套并存、禁互为引用**(Q3 甲案) | -| 2 | 泛光实现细节取舍 | 走 Q1 丙案主路径 shader 距离场衰减(非 draw_rect 分段叠层/非 draw_polygon 渐变近似);a 案程序绘制兜底件**未实例化启用**(共存实测未撞墙,L3 预授权①未触发;兜底路径留档于卡片 T1,不落码) | shader 内缘带 SDF+圆角掩码+`mask_rect` 豁免区(预读徽章位)一步到位;带宽/α/软边/圆角全参数化,调参不改代码 | -| 3 | shader uniform 命名与参数表 | `glow_col / glow_alpha / band_frac / soft / corner / cell_px / mask_rect`(`cell_type_glow.gdshader:12-18`);参数值全部由 ui_kit 常量注入(`cell_type_glow_layer.gd` set_shader_parameter),shader 内默认值仅占位 | 命名与 art-bible §4.2 v2 呈现参数一一对应(α170/cell÷8);hint_range 限幅防误调出界 | -| 4 | 呼吸相位驱动写法 | **未启用呼吸**(Q5 甲案静态);shader 相位通道未预留 uniform,`_process` 呼吸仅接触带既有件在跑(3 rad/s≈0.48Hz,减动效 `motion_scale<1.0` 停格)。微光相位门控复用 `set_dig_glow_enabled`(与接触带同源) | Q5 甲案下 V8 空转;若出口后追裁呼吸再议,本批不预设通道 | -| 5 | 冒烟/探针断言取值与夹具板配置 | 冒烟夹具:seed 4242 L1 板+`install_board`+novice 驱动到未开邻格 ≥5(初始展开覆盖 8 邻→必驱动);八邻派八型(attack/heal/pierce/blast/magic/defense/action/gp)+哈希兜底九型全集;清单外负样本 `"keystone"`;封锁集返回 null;契约 1 双实例 = 同板同 12 步 novice 序列逐步对照 digest(hero/已开集/旗数/AP/相位)。探针 case⑰ 活板面 = 生产身份面(真实点击挖开)。board_shot 双帧 = 每关 18 步 novice+`motion_scale=0.5` 停格+生产身份接线 | 夹具确定性(全缸可复现);「同板同序列」隔离唯一定位在开关;双帧前置停格否则接触带相位漂移污染「非生效格零变化」 | -| 6 | 取样阈值 provisional 数值 | 带内判据 `band_px = cell×0.125`(L1 格边 46 → 5.75px);互辨判据线 CR ≥ 1.20(相邻组,合成空间模型域);golden 容差沿用 ≤16 差/≤2% 占比(render_gate 现值,未新立);砖心灰度扰动阈值以「带外零变化」等效承载(禁侵判据 = 变化像素全部落在内缘带内) | 首版取严:判据线 1.20 高于实测最弱对 1.232 的 97%;模型域与实测差(shader 距离场权重非扁平混合)由探针实测兜底,故阈值不收紧到模型值 | -| 7 | 提交切分与 worktree 分支命名 | 分支 `iter30-glow-20261017`/worktree `g-plan2-iter30-glow`;提交按「实施本体(色板/shader/承载件/board_view 生命周期)→ 断言三件(冒烟段/单测/探针段)→ 渲染取证(board_shot 双帧)→ reports/ 三份产出物」切分;自产 `.uid` 4 个随件提交(type_glow_test.gd.uid 为批末编辑器导入通行补齐) | 与 iter29 单批十提交的颗粒度对齐;合回前 `git merge master`(master 已到 bd6ab32e,本分支基于 d984d47c)再重闸 | - -**追认请求**:以上 7 项如无异议即视为追认;有异议项指出#号,按 L1(自救)或重裁处理。 - -**追认结果(2026-10-17 用户令「追认没有问题」)**:以上 7 项全部追认通过,无异议项。 diff --git a/reports/iter30-反哺点-2026-10-17.md b/reports/iter30-反哺点-2026-10-17.md deleted file mode 100644 index d2d4f7ba..00000000 --- a/reports/iter30-反哺点-2026-10-17.md +++ /dev/null @@ -1,31 +0,0 @@ -# 迭代 30 卡① 未开格类型徽章批 · 反哺点清单 - -- 批次:迭代 30 卡①(分支 `iter30-glow-20261017`);依据卡片 §5 同步面(v1.3 执行口径:实现批禁写 `design/`,逐条列清单、用户会话裁决后归文档批落文) -- 完成日 2026-10-17;清单条数 7 = 卡片 §5「反哺点 · 列清单待裁」行数(V9 对表;`active.md` 行属本批已更新例外、`game/presentation/views/*`+`game/smoke/*` 行属实施本体,均不计入) - -| # | 文件 · 节 | 改成什么 | 依据 | -|---|---|---|---| -| 1 | `design/gdd/06-待办清单.md` :429-435 | ①「未开格类型微光」条目状态:待办 → **完成**(批末重闸全绿后);②:431「候选值,样张批冻结」色相措辞修正为「色相 = art-bible §4.2 样张 v2 冻结值(既裁),本批只动明度」——06 :431 自身 2026-09-30 口径已声明「只承载实施状态、不承载定义」,措辞修正属批内机械面;③:435 旧读数(bonus_pick_overlay 位点)刷新为现行读数;④明度档 provisional 值登记去向 = 第 4 条 art-bible 修订条目,复核义务移交样张卡 | Q2 甲案裁定;art-bible :66/:551 冻结依据;§5 行 1 | -| 2 | `design/gdd/systems/表现与支撑/HUD框架.md` :140 / :269 | ①:140 实装状态行「游戏内待实施批」→「**已实装(迭代 30 卡① 2026-10-17)**」;②:269 验收行去「待实施批落地后验收」括注、转正式验收行;③文首状态行换代(同批体例) | Q4 丙案默认开已入库;§5 行 2 | -| 3 | `design/gdd/08-Alpha版本标准.md` 「五 · 表现」表 | 新增「未开格类型微光」行:待做 → **在役**;行内注「明度档 provisional 值(Q2 甲案),战斗一屏样张批复核转正」;文首状态行换代 | Q2 甲案;Alpha 判据(阻塞主流程/无法联调才算 alpha 阻塞——呈现增强不属);§5 行 3 | -| 4 | `design/art/art-bible.md` §4.2 修订条目(Q2 项) | 以修订条目登记五组明度档 provisional 值:芥末黄 #F7DF43/黄绿 #68D042/青 #30A6A6/紫罗兰 #7B5BD6/绯红 **#A61D37**(冻结 #FF2D55 的 V=0.65 档,色相零移动);注明生成口径 = 渲染合成空间(伽马)阶梯、相邻组模型 CR 1.245/1.234/1.239/1.270、复核归样张批。§4.2/§4.6.3 权威面零改动;§2.1 修订条目不追加(Q5 甲案静态、条件分支不触发) | Q2 甲案;2026-10-17 停机呈报用户裁「换更暗档 #A61D37」留痕(实现报告 §二-1);§5 行 4 | -| 5 | `roadmap.md` 迭代 30 行 | 编入笔已在案(2026-10-16 用户令);批内状态更新 = 卡① 完成(卡②样张批、卡③观感批串行待启),批末重闸 `--code` 全绿读数 | 三卡串行序位;§5 行 5 | -| 6 | `design/gdd/06-待办清单.md`(Q3 甲案追加) | ①「卡顶带与格面带分工」说明写入文档注记面(art-bible §4.2 或 HUD框架 微光节):两带并存、TG_* 卡顶带管货架卡面、TG_GLOW_* 管未开格微光,禁互为引用;②另登 06 一条新待办「卡顶色带与格面微光两带统一」(TG_* 迁移 = 原 T3 条件卡内容,Q3 甲案不并入本批) | Q3 甲案(不并入);§5 行 6 | -| 7 | `design/gdd/07-体验验证清单.md` | 新增实机目检人闸条:五组互辨观感(一眼可分)/不遮数字/出圈灭/整屏不脏+群伤暗档(#A61D37)实机辨识;人闸不可代、登记不阻塞。目检项全文已进 `reports/iter30-实现报告-2026-10-17.md` §五 总清单 | V10;§5 行 7 | - -## 回写结果(2026-10-17 用户令「反哺点可以都进行回写」) - -七条全部回写完成(文档批 `iter30-fb-20261017`,2026-10-17): - -- 第 1 条(06 待办清单)→ **已回写**:条目状态待办→已完成(入库 7ffd1dc0、冒烟 1151/0、单测 34 套、探针 case⑰、07 ㉘ 人闸五项);色相措辞修正为「样张 v2 冻结既裁值」;2026-10-05 实查读数刷新(bonus_pick_overlay.gd 已改名 curio_pick_overlay.gd:97、TG_* 五族在役 ui_kit.gd:49-53、裸 Color8 读数作废);明度档 provisional 值登记去向按第 4 条落 art-bible v3.15 文首登记 -- 第 2 条(HUD框架)→ **已回写**:实装状态行转「已实装(迭代 30 卡① 2026-10-17 入库,合并 `7ffd1dc0`)」;验收行转正式验收(去「待实施批落地后验收」括注);文首状态行换代 v0.19 -- 第 3 条(08)→ **已回写**:「五 · 表现」表新增「未开格类型微光(五组色相+明度档)」行(在役;明度档 provisional 值,样张批复核转正);文头状态行换代 v1.9 -- 第 4 条(art-bible)→ **已回写**:五组明度档 provisional 值+生成口径(渲染合成空间伽马阶梯、相邻组模型 CR 1.245/1.234/1.239/1.270、判据线 1.20、实测最弱对 1.232、群伤暗档停机呈报留痕)落 v3.15 文首登记;§4.2/§4.6.3 权威面零改动、§2.1 未追加(Q5 甲案静态);头注「现行为」漏更顺带订正 v3.11→v3.15 -- 第 5 条(roadmap)→ **已回写**:迭代进度行与迭代 30 表行状态列同步卡①已入库(2026-10-17,7ffd1dc0;②③待 `/iter` 发令) -- 第 6 条(06 Q3 甲案追加)→ **已回写**:两带分工注记落 HUD框架 微光节口径史注记后(卡顶带=条目级静态色带/格面微光=棋盘格内动态微光,禁互为引用);06 新增「卡顶色带与格面微光两带统一」待办条 -- 第 7 条(07)→ **已回写**:新增 ㉘ 节五项人闸(五组一眼可分/不遮数字〔环不外溢〕/出圈灭入圈复亮/整屏不脏/群伤暗档 #A61D37 观感〔provisional,读数归样张批〕),文首状态行换代 v1.5 - -## 附:不占反哺点条数的遗留(归实现报告 §六) - -- 阔视野带 desc「类型微光范围 8 格→12 格」与卡 §4「微光不随视野扩」冲突(`treasure_items.tres:47` 存量文本)——属数据文本批处置,非 design/ 文档同步面。 -- `type_glow_test.gd.uid` 已由批末编辑器导入通行补齐并随批提交(该件平时只经 `--script` 跑);库内另有 9 个存量未跟踪 `.uid` 属卫生缺口,留卫生批/文档批处置。 diff --git a/reports/iter30-实现报告-2026-10-17.md b/reports/iter30-实现报告-2026-10-17.md deleted file mode 100644 index 1616e360..00000000 --- a/reports/iter30-实现报告-2026-10-17.md +++ /dev/null @@ -1,92 +0,0 @@ -# 迭代 30 卡① 未开格类型徽章批 · 实现报告 - -- 批次:迭代 30 卡①「未开格类型徽章批」(卡片已退役——git 历史可考,原「未开格类型徽章批」**v1.4**) -- 分支 `iter30-glow-20261017`/worktree `g-plan2-iter30-glow`;闸口径 = 本批只碰 `game/` → `tools/run_all_gates.sh --code` -- 完成日 2026-10-17;三卡串行序位第 1(卡②战斗一屏样张批、卡③二三关棋盘观感批不在本会话范围) -- 裁决基线:Q1 丙(shader 为主、程序绘制兜底)/Q2 甲(明度档 provisional 值本批定、样张批复核转正)/Q3 甲(TG_* 两带统一**不并入**)/Q4 丙(默认开)/Q5 甲(静态无呼吸);v1.4 开工前预授权 U1 四项(T0-③ 判据自判+调参上限 2 轮、卡③ Q2 判据自动裁、卡③目标带批内自定、L3 分类预授权) - -## 一、各任务卡状态 - -| 卡 | 状态 | 要点 | -|---|---|---| -| T0-① 归组表 | ✅ | 九 cell_type → 五组封闭表落 `ui_kit.gd:106 glow_group_for_cell_type`(attack/defense/weaken/action/gp→增益/heal→治疗/pierce→穿刺/blast→群伤/magic→魔法;清单外 → GLOW_NONE+显式登记,禁静默空光)。大宝箱(未来第十型)按 reward_economy :106 归通用增益组的路径在注释与单测负样本留位 | -| T0-② 明度档 provisional 值 | ✅ | 五档按**渲染合成空间**(伽马)单调阶梯定值(生成口径订正见 §二-3);相邻组模型 CR = 1.245/1.234/1.239/1.270(判据线 1.20),实测最弱对 1.232 | -| T0-③ 路线原型帧 | ✅ | 判据自判(U1-①):三条像素判据全过——①五组并列去色相模拟仍可分(V6 同口径抽检)②砖心数字字形占位区灰度扰动 ≤阈值(V4)③接触带不越圈、非生效格零变化(V4)。调参 2 轮内收敛(未触上限)。shader 与 `_desat_mat` 共存实测**未撞墙**(L3 预授权①未触发),丙案主路径全程有效、a 案兜底未启用 | -| T0-④ 基线与行号复核 | ✅ | golden 基线 2026-09-30 代三图判读有效(本批 off 帧漂移 0.10–0.13%,见 §三);未重制任何基线 | -| T1 实装 | ✅ | 色值单点 `ui_kit.gd:87-95 TG_GLOW_*`;shader 面 `cell_type_glow.gdshader`+承载件 `cell_type_glow_layer.gd`(CanvasItem 距离场,uniform 参数化);作用集与生命周期 `board_view.gd:329 _recompute_glow`(= `_diggable` ∩ 身份可查 ∩ 灯光区 − r0)、`:355 set_type_glow_enabled`(Q4 丙开关,生产写入面=组合根单点)、`:859 set_dig_glow_enabled` 相位门控与接触带同源;`type_glow_probe():1209`/`cell_rect_probe():1217` 取证面 | -| T2-① 冒烟断言段 | ✅ | `smoke_all.gd:1756 _smoke_type_glow` 八相 24 项新断言(作用集恒等/九型映射/清单外登记/封锁格/解封复位/开关两态/换图重算/契约 1 双实例) | -| T2-② 单测 | ✅ | `tests/unit/presentation/type_glow_test.gd` 五段 51 检查;登记 `run_all.gd:80`(33→34 套件) | -| T2-③ 探针走查段 | ✅ | `ui_input_probe.gd:495` case⑰(活板面:作用集恒等/真实挖开灭/移动复亮出圈灭/相位门控/两态零扰动);十八断言全绿 | -| T2-④ 渲染闸双帧 | ✅ | `board_shot_probe.gd` on/off 双帧+`_check_dual_frames:156`;三关 glow=2/4/4、outside=0、生效格实绘非空;off 帧 golden 0.13/0.11/0.10%(≤2%)。修通记录见 §二-2 | -| T4 产出物 | ✅ | 本报告+代拍板追认单+反哺点清单三份落 `reports/` | - -冒烟合计 **1151 项全绿**(基线 1127+本批新增 24);单测 **51/51**(34 套件全绿)。 - -## 二、停机呈报与裁定留痕 - -### 1. 群伤组微光色值触碰冻结色相(§8 L3——唯一一次停机呈报) - -- **事实**:群伤组(blast) provisional 初版取 #FF1A31,与 art-bible §4.2 冻结绯红 #FF2D55 的 HSV 对照 ΔH = 5.40°、ΔS = +0.075(V 不变)——色相朝纯红移动,侵蚀「冻结绯红刻意错开危险红」的间距,属翻动 §4.2 五组色相既裁冻结面(Q2 复核结论明令 L3 停机呈报,U1 预授权不含此项)。 -- **呈报**:四选项交用户裁(A 维持 #FF1A31=翻色相/B 退回纯 V 缩放更深档/C 换更暗档 #A61D37/D 停机回 Q2 复议)。 -- **裁定(2026-10-17 用户)**:**「换更暗档 #A61D37」**——冻结 #FF2D55 的 V=0.65 明度档,色相零移动(H=348.57°/S=0.824 逐位不动)。 -- **落地与复验**:`ui_kit.gd:91` 改值+头注稽核史登记(:72-86);复跑判据源探针与单测全绿。现五组 ΔH:BUFF 0.08°/HEAL 0.13°/PIERCE 0.00°/MAGIC 0.00°/AOE 0.042°——全部满足「只动明度、不动色相」。 - -### 2. board_shot_probe 双帧取证「glow=0」缺陷(批内自救,非停机项) - -两次实跑三关 glow=0:第一次根因 = 裸视图 `_dig_glow=false`(加 `set_dig_glow_enabled(true)` 修复);第二次根因 = **裸视图从未接身份解析回调**(生产由 main.gd:251 接线,`_recompute_glow` 拿不到身份 ⇒ 作用集恒空、双帧比对空转、PASS 假绿)。修复 = `board_shot_probe.gd:83` 接生产同源 `_probe_identity_lookup:146`(板在守卫+Active 相位守卫+`query_reward_identity` 只读代理,相位前提:每轮 settle_batch 末尾 `_exit_distribution` 已 `notify_round_start`)。附带排一个 Godot 坑:`Callable.bind()` 动态派发对类型化参数做 Object 硬校验(「Cannot convert argument 2 from Object to Vector2i」)→ 改成员现值+直接方法引用(代码注释留痕)。 - -### 3. 明度阶梯生成口径订正(T0-② 内自救) - -首版按 CIE L*(线性域)排档,把群伤/魔法排反(绯红线性亮于紫罗兰,但伽马空间绯红 G+B 通道低、合成后更暗——实测最弱对 CR 仅 1.05)。订正 = 阶梯改在**渲染合成空间**排(引擎 canvas 混合在帧缓冲 sRGB 空间做线性插值,色弱玩家看到的是合成值);合成模型「带内均值 ≈ 0.49×色值 + 0.51×瓦片(BRICK #C9AF83)」,模型域与实测差 = shader 距离场权重非扁平混合 ⇒ 互辨判据终审在渲染取证探针实测(`ui_kit.gd:78-86` 头注留痕)。 - -## 三、闸读数表 - -| 闸 | 读数 | 判定 | -|---|---|---| -| 冒烟(run_smoke.py) | 1151 项/0 失败(新增 24 项:八相全绿) | 绿 | -| 单测(run_all.gd) | 34 套件全绿;type_glow_test 51/51 | 绿 | -| ui_input_probe | 十八断言全绿(⑰ 新增;活板面 glow=2、相位门控两态零扰动) | 绿 | -| type_glow_shot_probe(判据源探针) | glow_cells=5、groups=[1–5]、changed_total=4760、changed_outside=0;相邻组实测 CR 最弱对 1.232(组2/组3)、组4/组5=1.423 | 绿 | -| board_shot_probe 双帧(on/off) | L1 glow=2 changed=1912 outside=0;L2 glow=4 changed=3816 outside=0;L3 glow=4 changed=3792 outside=0(band_px=5.75 = 格边 46×0.125) | 绿 | -| golden 逐像素(off 帧 vs 2026-09-30 基线) | L1 0.13%/L2 0.11%/L3 0.10%(≤16 差/≤2%) | 绿 | -| 菜单 golden | menu_boot 0.14% | 绿 | -| 静态扫描(09) | 相对基线「改善」(批内两处新增红已修:R1A 无类型容器、文件头 9 行;基线存量红 fp=4354b2aa72a7 不属本批) | 绿 | -| render_gate.sh 整闸 | 全绿(shot_probe 七屏 A-D/fx 取证/双帧/golden 四图/残留 0) | 绿 | - -> 双帧 glow 格数(2/4/4)低于判据源探针(5)是**真实面与夹具面的差异**:探针接 settlement 真实 `query_reward_identity`,作用集随当板摇号与 18 步 novice 揭示态而定;五组齐现的互辨取证在判据源探针(夹具面)承载,两面分工不混。 - -## 四、变异验证记录表(新建断言段的注入实验) - -| # | 变异点(file:行) | 注入内容 | 跑的闸 | 红输出(实录) | 还原结论 | -|---|---|---|---|---|---| -| M1 | `ui_kit.gd:111` | `"heal"` 错映 GLOW_BUFF | 单测 type_glow_test | `[FAIL] 九型封闭:heal → 组1(期望组2)`(1/51 失败) | ✅ 还原后复跑 51/51 | -| M1' | 同上(保留叠加) | 同上 | 冒烟 run_smoke.py | `[FAIL] V2 九型→五组逐格映射 … 违例:(2, 1):heal→组1(期望组2)` | ✅ 同轮还原 | -| M2 | `board_view.gd:344-349` | 清单外 cell_type 静默跳过(去 `_glow_errors` 登记) | 冒烟(与 M1 同轮,断言足迹不相交) | `[FAIL] V2 清单外 cell_type 显式登记(errors=[])`+`[FAIL] V1 封锁格零登记(errors 仍仅清单外一条——[])` | ✅ 还原后复跑全绿 | -| M3 | `board_view.gd:874` | 相位切换不重算作用集(注掉 `_sync_glow_to_units` 内 `_recompute_glow`) | 冒烟 | `[FAIL] V1 作用集恒等:微光格集合 == _diggable ∩ 身份可查(期望 5,实测 0)` | ✅ 还原后复跑全绿 | -| M3' | 同上 | 同上 | ui_input_probe | `FAIL — case⑰ 结算相位未灭(作用集 1 格——相位门控破)` | ✅ 同轮还原 | -| M5 | `board_view.gd:332-337` | 微光派生路径误触玩法 API(`_recompute_glow` 内 `settle_batch(flag_place)`——契约 1「纯派生零玩法写入」破坏面) | 冒烟 | `[FAIL] 契约 1 同板同序列 on/off 两态结算逐位一致 … 第 0 步(move)后摘要分叉`+`[FAIL] 契约 1 对照前提:同序列 ≥5 步(实测 0)` | ✅ 还原后复跑全绿 | -| M4 | `ui_kit.gd:92` | `TYPE_GLOW_ALPHA := 0.0`(不绘) | render_gate.sh | 三关全红:`微光开帧整板零变化(微光未生效)`+每生效格 `零实绘像素(微光空转)`;闸 exit 1 | ✅ 还原后整闸复跑全绿 | - -五组变异覆盖五类断言面:归组封闭(M1)/禁静默空光(M2)/生命周期接线(M3)/契约 1 零玩法写入(M5)/像素实绘(M4)。变异残留零检出(`grep M[1-5] 变异` 全库为空)后才进的批末重闸。 - -## 五、实机目检总清单(V10 人闸——登记不阻塞) - -> 人闸不可代。以下项待用户实机过目;T0-③ 原型帧三道判据为目检第一道(已自判过,见 §一),批末本清单为第二道。 - -| # | 目检项 | 判据 | 状态 | -|---|---|---|---| -| 1 | 五组一眼可分 | 色相+明度双码下去色相仍可分组(机检预判已过:最弱对 CR 1.232;误读率终判归样张批 §4.6.3 :325 既裁) | 待用户目检 | -| 2 | 不遮数字 | 微光不入砖心数字字形占位区(机检已过:带外零侵入、砖心留白;V4) | 待用户目检 | -| 3 | 出圈灭 | 英雄移出可挖域/相位切结算即灭(机检已过:case⑰) | 待用户目检 | -| 4 | 整屏不脏 | 默认开态下棋盘观感无杂乱感(「很丑」质疑的终审位) | 待用户目检 | -| 5 | 群伤组暗档观感 | #A61D37 实机辨识度(停机呈报裁定的暗档,样张批复核转正前的 provisional 态) | 待用户目检 | - -「入册 07-体验验证清单」列反哺点(见反哺点清单第 7 条)。 - -## 六、遗留读数义务 - -1. **阔视野带 desc 与微光口径冲突(存量观察,不占反哺点条数)**:`game/data/tables/treasure_items.tres:47` 阔视野带(wide_scout_band)desc 写「类型微光范围 8 格→12 格」,与卡 §4「不扩微光环半径——贴身 8 格是已拍板口径(HUD框架 :167),阔视野带类道具一律不扩微光」冲突;且实现面微光作用集恒为 `_diggable`(英雄 8 邻)子集,`light_radius_bonus` 只放大灯光区(`FOG_RADIUS + _fog_lantern` 门控),不可能把微光扩到 12 格。desc 属数据文本滞后(早于本批写成),建议归秘宝/数据文本批订正——本批不改数据表(只碰代码与断言面),仅登记。 -2. **`.uid` 伴生状态**:本批自产 4 个 `.uid`(cell_type_glow.gdshader/cell_type_glow_layer.gd/type_glow_shot_probe.gd/type_glow_test.gd)均随件提交(type_glow_test.gd 的 `.uid` 为批末编辑器导入通行补齐——该件平时只经 `--script` 跑、编辑器不导入,故开发期未生成)。库内另有 9 个**存量**未跟踪 `.uid`(layout_probe/screen_flow_probe/save_rng_roundtrip/board_generator/config_db_cross_validator/config_db_resolver/minesweeper_rules/battle_narrator/hud_presenter 各测试件)属卫生缺口,不随本批提交,留卫生批/文档批处置。 -3. **golden 基线未重制**:本批 off 帧对 2026-09-30 代三基线漂移 0.10–0.13%(接触带静态化预期面,契约 6 未触发),基线原样在库。 -4. **群伤暗档 provisional 属性**:#A61D37 为 Q2 甲案 provisional 值,复核转正归战斗一屏样张批(卡②);样张冻结值若与本值不一致,走 `ui_kit` 色值单点改值+冒烟/单测色值断言同步(机械面,不构成路线翻案)。 -5. **V6 误读率指标**:本批只跑机检抽检预判(去色相五组可分),误读率定量终判归样张批(§4.6.3 :325 既裁),本报告不代拍。 diff --git a/reports/需求卡片-存档制数据层改造批-2026-10-18.md b/reports/需求卡片-存档制数据层改造批-2026-10-18.md index c81ed365..1208c4a0 100644 --- a/reports/需求卡片-存档制数据层改造批-2026-10-18.md +++ b/reports/需求卡片-存档制数据层改造批-2026-10-18.md @@ -42,7 +42,7 @@ | F5 | SaveManager 为 autoload(工程序 ConfigDB→RngService→SaveManager→MetaProgression);MetaProgression 持有 `var save: SaveManagerCore`,`_ready` 取 `/root/SaveManager` 一次——消费面对存档的引用是单实例单引用;全部访问器为 `save.xxx()` 动态分发、无缓存 | `game/project.godot:21`;`game/core/meta_progression.gd:9`/:21-25/:54 | | F6 | 探针/冒烟隔离机制在役且面比初查大:`_META_SMOKE_PATHS` 注入清单 **18 条**(smoke_all.gd:5701-5708);另有 `user://smoke_save_*` 15 条(:6499-6511)、boot/lifecycle/lifecycle_resume/run_lifecycle 段(:277/:321/:463/:594)、`test_pacing_queue_save`(pacing_queue_test.gd:28)、`smoke_tune_probe_*`(ui_tune_probe.gd:167/:171)、probe tag 族(probe_ui_util.gd:98-121,10 探针 15 处调用);`attach_path` 直接消费 8 处+isolate_save 间接 15 处 | `game/smoke/smoke_all.gd:5701-5708`/:6499-6511 等;`game/smoke/probe_ui_util.gd:98-121` | | F7 | 文档侧早已预写多档去向:存档序列化.md P2 后置表载「多存档槽位|单档 MVP(2026-09-21 裁决);多档等有真实需求再立项」——本批即该条预写的「真实需求」落地;同文 :61 现行口径=「存档是单文件 JSON(user://save.json)」;:20 系统范围负责表载「单档 JSON 存档的域划分与读写约定」 | `design/gdd/systems/表现与支撑/存档序列化.md:165`/:61/:20/:16 | -| F8 | 近期闸基线:冒烟 1151/0、单测 51/51(34 套件),载于 iter30 实现报告——开工日 T0 重测取当期值 | `reports/iter30-实现报告-2026-10-17.md:23`/:46-47 | +| F8 | 近期闸基线:冒烟 1151/0、单测 51/51(34 套件),载于迭代 30 卡① 合并提交 `7ffd1dc0` 的回执读数(实现报告已退役,git 历史可考)——开工日 T0 重测取当期值 | git 提交 `7ffd1dc0`(迭代 30 卡① 合并) | ## 3. 设计契约(红线,违反 = L3 停机呈报) diff --git a/roadmap.md b/roadmap.md index 76be4d80..65080a92 100644 --- a/roadmap.md +++ b/roadmap.md @@ -63,7 +63,7 @@ | 迭代 27 | 已完成(2026-10-14) | 已退役(git 历史可考) | 2026-10-14 | — | 已退役(git 历史可考) | | 迭代 28 | 已完成(2026-10-15) | 已退役(git 历史可考) | 2026-10-15 | — | 已退役(git 历史可考) | | 迭代 29 | 已完成(2026-10-16) | 已退役(git 历史可考) | 2026-10-16 | — | 已退役(git 历史可考) | -| 迭代 30 | 已完成(2026-10-17) | 已退役(git 历史可考) | 2026-10-16 | — | reports/iter30-实现报告-2026-10-17.md | +| 迭代 30 | 已完成(2026-10-17) | 已退役(git 历史可考) | 2026-10-16 | — | 已退役(git 历史可考) | | 迭代 31 | 待开工 | reports/需求卡片-代码术语刷新批-2026-10-18.md、reports/需求卡片-凭证件裁削批-2026-10-18.md | 2026-10-18 | ≈1.5 周 | — | - 历史行的「—」= 该列事实不可考:迭代 1~8 早于需求卡片制;编排时点与预计周期不再回溯,细节查 git 提交史。 From ca86d18811ac2779f7ed5fdeb0da4b68ac3eda8f Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 15:08:38 +0800 Subject: [PATCH 15/59] =?UTF-8?q?fix(06):=20=E9=98=94=E8=A7=86=E9=87=8E?= =?UTF-8?q?=E5=B8=A6=E6=96=B0=E6=9D=A1=E5=8E=BB=E6=8E=89=E9=80=80=E5=BD=B9?= =?UTF-8?q?=E8=AF=8D=E3=80=8C=E9=9A=8F=E6=89=B9=E3=80=8D=E2=80=94=E2=80=94?= =?UTF-8?q?=E6=94=B9=E3=80=8C=E5=9C=A8=E8=BF=99=E6=AC=A1=E6=94=B6=E5=B0=BE?= =?UTF-8?q?=E4=B8=AD=E9=80=80=E5=BD=B9=E3=80=8D=EF=BC=8808=20doc=5Fterm=20?= =?UTF-8?q?=E6=96=B0=E7=BA=A2=E4=BF=AE=E6=AD=A3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/gdd/06-待办清单.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index 532eae41..68e500dc 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -313,7 +313,7 @@ #### 阔视野带效果表述与类型微光口径冲突(2026-10-20 登记,来源=批次移交,设计面=工程直入) -**现状**:迭代 30 卡①实现报告登记的存量冲突(报告随批后收尾退役,git 历史可考):[秘宝](systems/跨局循环/秘宝.md) 普通档表「阔视野带」行一句话写作「类型微光范围 8 格→12 格」,`game/data/tables/treasure_items.tres` 该行 `desc` 同口径;但 [HUD框架](systems/表现与支撑/HUD框架.md) 迷雾节配套拍板已定「类型微光不随视野扩大(贴身 8 格、微光锚=可挖域)」,实现面微光作用集恒为 `_diggable` 子集,该件实际效果是 `light_radius_bonus` 扩灯光区(迷雾视野 8→12),不扩类型微光。两处表述属提灯功能承接时期的遗留措辞。 +**现状**:迭代 30 卡①实现报告登记的存量冲突(报告已在这次收尾中退役,git 历史可考):[秘宝](systems/跨局循环/秘宝.md) 普通档表「阔视野带」行一句话写作「类型微光范围 8 格→12 格」,`game/data/tables/treasure_items.tres` 该行 `desc` 同口径;但 [HUD框架](systems/表现与支撑/HUD框架.md) 迷雾节配套拍板已定「类型微光不随视野扩大(贴身 8 格、微光锚=可挖域)」,实现面微光作用集恒为 `_diggable` 子集,该件实际效果是 `light_radius_bonus` 扩灯光区(迷雾视野 8→12),不扩类型微光。两处表述属提灯功能承接时期的遗留措辞。 **归属**:秘宝.md 普通档表该行 + treasure_items.tres 该行 desc(数据文本订正批;只改文字、不改机制) From 76825590c28b0ab3ff33b92a5de92ab98860240c Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 15:27:25 +0800 Subject: [PATCH 16/59] =?UTF-8?q?docs(iter31=20=E5=8F=8D=E5=93=BA=E7=82=B9?= =?UTF-8?q?=E8=90=BD=E6=96=87):=20=E6=9C=AF=E8=AF=AD=E8=A1=A8=E8=A1=A5=20s?= =?UTF-8?q?eal=5F*=20=E5=A5=91=E7=BA=A6=E9=94=AE=E4=B8=8E=E6=95=88?= =?UTF-8?q?=E6=9E=9C=E8=AF=8D=E6=9D=A1=EF=BC=9B=E5=A5=87=E7=89=A9=E5=AE=8C?= =?UTF-8?q?=E7=BE=8E=E4=BF=9D=E9=99=A9=E8=90=BD=E8=A1=A8=E6=8C=87=E5=90=91?= =?UTF-8?q?=E4=B8=8E=E8=B1=81=E5=85=8D=E8=B4=A6=EF=BC=9B07=20=E3=89=99=20?= =?UTF-8?q?=E4=B8=83=E9=A1=B9=E7=9B=AE=E6=A3=80=EF=BC=9B=E7=BE=8E=E6=9C=AF?= =?UTF-8?q?=E4=BB=B6=E5=90=8D=20seal=5Fmark=20=E4=B8=8E=E8=A7=84=E7=BA=A6?= =?UTF-8?q?=E5=AE=88=E5=8D=AB=E4=BE=8B=E5=A4=96=E6=9D=A1=E6=AC=BE=EF=BC=9B?= =?UTF-8?q?06=20=E6=96=B0=E5=A2=9E=E7=8E=A9=E5=AE=B6=E9=9D=A2=E6=AE=8B?= =?UTF-8?q?=E7=95=99=E7=A6=81=E5=AD=97=E5=80=99=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 术语表:封印行补代码契约键 seal_*(原 flag_* 全族换代)与单字字形「封」;新增 seal_missed/forgive_seal_miss 词条;退役词表加 flag_*→seal_*;用语规范 B 类补第 4 条「被检查的禁字不算使用」与复扫口径 - 奇物.md:v3.18 件表注③「归独立批」指向改指迭代 31 卡②合回 commit 3e076e22;§1.3 补完美资格豁免走订阅式自有累加账 - 07:新增 ㉙ 节七个目检项(GP 显示、封印字样、结算来源名、seal_mark.png 加载、完美保险文案、稀有档三选一、豁免后第二份额) - interaction-patterns:perfect_broken 判据句读作「首次标错受检」(B=乙,代码零动) - art-bible v3.16/asset-path-map:封印印记件名 flag_seal.png → seal_mark.png,补 32×32 规格 - 06:新增「玩家面残留禁字清扫」候选条目(来源=批次移交,设计面=工程直入) --- design/art/art-bible.md | 4 ++-- design/art/asset-path-map.md | 2 +- design/gdd/06-待办清单.md | 10 ++++++++++ design/gdd/07-体验验证清单.md | 16 ++++++++++++++++ design/gdd/systems/冒险循环/奇物.md | 3 ++- design/gdd/ux/interaction-patterns.md | 2 +- design/gdd/术语表.md | 13 +++++++++++-- 7 files changed, 43 insertions(+), 7 deletions(-) diff --git a/design/art/art-bible.md b/design/art/art-bible.md index c402355c..8c20509c 100644 --- a/design/art/art-bible.md +++ b/design/art/art-bible.md @@ -1,6 +1,6 @@ # 美术圣经(Art Bible)— Dungeon Sweeper -> 项目:Dungeon Sweeper(扫雷 × 自动战斗 闯关 Roguelike)· 状态:**第 1–9 节定稿**(§6 环境/§7 UI/§8 资产规范/§9 参考与反参考已于 2026-09-23 v1.8 按 D1/D2/D4/D5 框架成文;D3=§5 角色已于 v1.6 落地、v1.7 抽离独立文档;框架 2026-09-22 用户拍板,原登记于中间产物修订指导,经裁决不入库,明细归状态记录 125);现行为 v3.15,历次修订明细见 git 提交史 +> 项目:Dungeon Sweeper(扫雷 × 自动战斗 闯关 Roguelike)· 状态:**第 1–9 节定稿**(§6 环境/§7 UI/§8 资产规范/§9 参考与反参考已于 2026-09-23 v1.8 按 D1/D2/D4/D5 框架成文;D3=§5 角色已于 v1.6 落地、v1.7 抽离独立文档;框架 2026-09-22 用户拍板,原登记于中间产物修订指导,经裁决不入库,明细归状态记录 125);现行为 v3.16,历次修订明细见 git 提交史 > > **Art Director Sign-Off (AD-ART-BIBLE)**:历次批均 SKIPPED(v1.8 §6–9 补全亦 SKIPPED)— Lean/Solo mode(非 PHASE-GATE;§6–9 已成文,full 门禁签核时机待用户表态) > 风格基调(2026-09-10 用户定稿):地牢题材但**非暗黑风**——轻快明亮的幻想冒险风,全年龄;像素风;角色 2~3 头身 @@ -164,7 +164,7 @@ - **装饰变体(未开格氛围层)**:覆尘完整砖之上叠加裂纹/碎石斑/物件级点缀等装饰;2026-09-29 v3.0 物件级解禁——物件级装饰(小石块/陶片/骨殖等)须走**专属装饰形状家族**(与信息元素形状语言隔离、灰度下不与任何逻辑元素同形),数量配额按图类型定(候选 3–5 种,样张 v3 冻结),一律残缺、内凹、低对比而自然后退(§3.4);零信息纪律(分布随机、与雷/安/类型零相关、灰度下禁止制造新分类特征、分布每板一次跨轮不复掷)以原则三为准,此处不赘。←原三 - **结果整格表达(已开格)**:已开格按当格结果整格表达(结果清单见原则三);画法——产资源格的家族物件纹样用 §3.1 道具点剪影语言(直线几何体)角嵌于砖缘,砖心与数字字形占位区留白(已开格仍承载数字);危险格巢穴纹较已开格更凶一档,形状+颜色双通道不变。←原三;P3 - **未开格预读通道(微光单通道)**:类型预读 = 类型微光单通道(色相+明度双码,色带 §4.2);色弱类型主通道 = 微光明度梯度(组粒度——组间互辨;§2 微光明度例外);格内零角嵌/箭头/加号类附加形(2026-09-28 用户裁「微光格只留微光」,退役史见 git 提交史)。←原一;原三 -- **旗(封印印记)**:插旗动作的叙事呈现 = **封印**(玩家可见专名,术语定义见 [术语表](../gdd/术语表.md)「封印」条;插旗动作面见《排雷玩法》)——旗 = 封印印记;封印色(§4.1,现行封印黑)与格内优先级栈位(§1.2)不变。封印特效(施印瞬间 + 印记常显形态)资产归清单 §4 演出类;旗印记纹理已落位、字形占位退役(迭代 9 卡⑬兑现;原 06 债务条目已完成移除)。←原一;P2;术语批 2026-09-25;封印紫批 2026-09-26;封印黑批 2026-09-28 +- **封印印记**:封印动作的叙事呈现 = **封印**(玩家可见专名,术语定义见 [术语表](../gdd/术语表.md)「封印」条;动作面见《排雷玩法》)——封印动作落在格上的印记称封印印记;封印色(§4.1,现行封印黑)与格内优先级栈位(§1.2)不变。封印特效(施印瞬间 + 印记常显形态)资产归清单 §4 演出类;封印印记纹理已落位(现行件=`seal_mark.png`,32×32 可选件)、字形占位退役(迭代 9 卡⑬已实现;原 06 债务条目已完成移除)。←原一;P2;术语批 2026-09-25;封印紫批 2026-09-26;封印黑批 2026-09-28 - **可挖域接触带微光(交互反馈层,2026-09-25 用户拍板)**:挖掘期,英雄格周界与可挖域(概念见《排雷玩法》动作合法性节;呈现义务见《HUD框架》可挖域指示)的接触面画呼吸微光——正交邻墙=该侧整条边,斜向邻墙=共享角点+向两侧各延伸半条边;光只画英雄格(空间)一侧、不进墙格(与装饰变体零冲突,数字砖心不涉);微光=空间的灯光边界(画法口径)。色相=蓝族浅一档(§4.2 蓝条;与主角蓝框的分层归样张批);呼吸=§2.1 挖掘期唯一在动元素,减动效停格。角点为斜墙与正交墙共享、不逐格归因,逐格指认=悬停金框(呈现交互归《HUD框架》悬停指示域)。←§2.1;§4.2;P1 - **墙体**:圆角砌块堆叠,禁尖刺装饰——尖刺专属危险语义,装饰禁止伪装逻辑差异。←原三 - **高墙瓦片体系(2026-09-26 定稿,样张批追认)**:未挖格=**一整块 32×32 自含凸起岩体**(方案甲核心定义);素材语义名——未开格素材=**墙瓦片**,已开格素材=**地面瓦片**(术语 2026-09-26 用户立)。**边界=墨线纪律**:墙瓦片与相邻格分界一律 1px 深墨线、直线贴格边、零锯齿;墨线职责=分隔,不追求与地面融合(Tiny Dungeon 样图实证调研后否决出局——TD 拼块套不进方案甲自含岩体定义,2026-09-25 终局维持方案甲;记录=git 提交 70d2320)。**光照=单一北受光**:北缘=墨线内侧 1px 微亮棱(就地取色提亮,禁宽亮带);西/东缘=墨线后直进纹理、不加修饰;南缘=墨线+立面窄暗条(约 1/3 格高,横层理叠石、禁竖条纹栅栏感)。**凹角**:角点单像素落线;南立面侧凹角加 1px 立面收头——带身与转角竖线同列收尾,禁悬空、禁突出(v9.1/v9.2 两版返工实证)。现行定稿=`game/assets/art/board/terrain_*`(16 唯一墙瓦片+5 地面瓦片变体;词表与查表逻辑见 `高墙瓦片词表(已落码 board_world.gd 查表,文件已退役)`)。**高墙感 D 投影档+整板悬崖(样张 v2 定稿 2026-09-28,用户 2026-09-27 四变体挑档)**:南临空墙格=立面口沿高光 2px `Color8(196,172,132)`+双段暗带(0.16/0.25 格边,黑罩 α0.60/0.82);北邻墙地面格=三段渐隐投影(顶带 0.22 格边,α0.28 起);整板悬崖=板底/右侧 `DEPTH_PX 8px` 暗面+列分隔竖缝+岩层横纹+口沿高光+接触 AO+底线收边+悬浮影(游戏 `board_world.gd` 同款结构件,样张脚本与游戏渲染常量同源——机检 F7 承载)。←原三;状态记录 164;样张 v2 批 2026-09-28 diff --git a/design/art/asset-path-map.md b/design/art/asset-path-map.md index 42262455..6173e83d 100644 --- a/design/art/asset-path-map.md +++ b/design/art/asset-path-map.md @@ -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)) | -| `board/` | 砖面/旗印记(三关换皮 + 封印旗;2026-10-06 对账更正——旧 `board_floor/wall/pillar_dungeon_*` 命名退役) | terrain_floor__.png(三关地面系)、flag_seal.png | +| `board/` | 砖面/封印印记(三关换皮 + 封印印记件;2026-10-06 对账更正——旧 `board_floor/wall/pillar_dungeon_*` 命名退役) | terrain_floor__.png(三关地面系)、seal_mark.png | ## 4. 坐标/朝向等工程侧约定备查 diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index 68e500dc..ea7dc883 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -689,3 +689,13 @@ **归属**:①`奇物.md` §1.1/§2.2/v2.2 行(已订正写入文档);②`奇物.md` §1.3(:121/:223/:229)与 `02-系统清单.md:49`(待裁) **状态**:已写入(design/gdd/systems/冒险循环/奇物.md v3.19——第①项专长凭证归类订正)+待裁决(第②项资源判据句,心智模型未对齐,不列候选不提前处置) + +--- + +#### 玩家面残留禁字清扫——图例/明细/日志/字形五处(2026-10-20 登记,来源=批次移交,设计面=工程直入) + +**现状**:迭代 31 卡① 已把 `game/` 的金币/插旗/雷格/惩罚格/`flag` 清零,但玩家可见文本仍残留「雷/排雷/插」五处(v3.15 命名纪律:玩家面禁「雷」,危险格对外风味=地下城陷阱/怪物巢穴):①`legend_overlay.gd:11` 图例行「插错可左键直接挖开…危险格吃**挖雷**惩罚」;②`status_slot_row.gd:42` 与 `settlement.tres:14` 明细来源名 `"mine_hit": "踩雷"`;③`battle_log_view.gd:194` 战斗日志「本板**完美排雷**已破——归因此封印」;④`board_fx_view.gd:102` 横幅「**完美排雷** ×2」;⑤`board_view.gd:737` 已开危险格单字字形 `glyph = "雷"`。①-④ 纯文案零风险;⑤ 改字形会动 golden 基线,须同步重制 C 档基准。开发注记面(`ui_kit.gd:37` 常量名 `RED_MINE` 与其注释)属内部语,按纪律保留。 + +**归属**:`game/presentation/` 与 `game/data/tables/settlement.tres`(走独立 worktree 批;⑤ 连带渲染基线) + +**状态**:待写卡 diff --git a/design/gdd/07-体验验证清单.md b/design/gdd/07-体验验证清单.md index fca4e440..23fd6bc9 100644 --- a/design/gdd/07-体验验证清单.md +++ b/design/gdd/07-体验验证清单.md @@ -302,3 +302,19 @@ | 3 | 出圈灭、入圈复亮 | 角色走远出 8 格圈→微光灭;走回→复亮;换图随旧图全重置 | | 4 | 整屏不脏 | 满圈微光同屏时棋盘不显脏、不抢焦点(焦点预算观感的人眼侧) | | 5 | 群伤暗档观感 | 绯红暗档 #A61D37(V=0.65 provisional)与其余四组同屏时的区分度、以及与危险红不误读的观感——读数归样张批复核 | + +--- + +## ㉙ 代码术语刷新与凭证件裁削批——玩家面目检(迭代 31 卡①/卡②;能力验证半=冒烟 1151 项 0 失败+单元 34 套全绿+对拍 120 局真差异 0 行+`feat_vouchers` 39 项全绿+变异六条五红) + +> 卡① 是纯重命名批(行为零变化),卡② 删两件凭证、把完美保险改为专长订阅式。机检能证明词面清零、数值零漂移与验收组全绿,但玩家面「旧词是否真的不见了、贴图是否还在、豁免的实际观感」仍要人眼看。登记不阻塞(2026-10-12 真人检测立规)。 + +| # | 目检项 | 判据 | +|---|---|---| +| 1 | 商店货币显示 | 商店界面货币显示「GP」,不再出现「金币」 | +| 2 | 图例/HUD 封印文案 | 图例与 HUD 显示「封印/封印印记」,不再出现「插旗/旗」;板面单字字形现为「封」 | +| 3 | 结算明细来源 | 结算明细来源显示「封印命中/封印未中」 | +| 4 | 封印印记贴图三关加载 | `seal_mark.png` 在 L1/L2/L3 三关均正常加载,非字形回退态 | +| 5 | 完美保险卡面文案 | 专长卡面文案读作「本场首次封印落空,不计入完美封印判定」,零「雷」字 | +| 6 | 稀有档三选一 | 三选一带不再出现同调电池/完美保险;稀有档仅剩 ap/rap/time_sand 三种 | +| 7 | 豁免后的完美第二份 | 带完美保险专长时,首次标错后清图仍能拿到「完美第二份」(订阅式豁免的实际观感) | diff --git a/design/gdd/systems/冒险循环/奇物.md b/design/gdd/systems/冒险循环/奇物.md index 4719d536..19f0dea7 100644 --- a/design/gdd/systems/冒险循环/奇物.md +++ b/design/gdd/systems/冒险循环/奇物.md @@ -104,7 +104,7 @@ 惊巢反制=退役进素材库(不迁入)。 -**资源类迁出件(2026-10-18 用户裁)**:完美保险自资源类迁入专长——理由:它给的是**规则豁免**而非可调动的余量(§1.1 判据「给规则的是专长」),效果=本场首次封印落空不计入完美封印判定。旧「资源类成员」归类系 2026-10-08 框架批写入、无用户裁断支撑,随本次改判注销。专长行的触发器规格与代码实现(含效果引擎词表扩签)归独立批,见 06 登记。 +**资源类迁出件(2026-10-18 用户裁)**:完美保险自资源类迁入专长——理由:它给的是**规则豁免**而非可调动的余量(§1.1 判据「给规则的是专长」),效果=本场首次封印落空不计入完美封印判定。旧「资源类成员」归类系 2026-10-08 框架批写入、无用户裁断支撑,随本次改判注销。专长行已于迭代 31 卡② 落表(合并 `3e076e22`):`feats.tres` 单行 `when counter(insurance_used) lt 1` 承载「本场首次」,效果类型 `forgive_seal_miss` 随引擎扩签;配额按净删重裁(rare 9→7、总量 104→102)。 ### 扩签登记(迭代 20 实装已承载——2026-10-12 追认④写入文档换代) @@ -231,6 +231,7 @@ **补给类内部的异质性(统一表述)**:凭证全部即时消尽——不存在「持有凭证」这种状态;异质性不在凭证上,而在**被写入的系统资源的寿命**上:GP 钱包 / 生命 / 刷新存量 = 冒险级,储备池 = 节点级,时沙暂记 = 至下一战首轮兑付(系统资源清单对齐「凭证件表(新 3+留任 2)」节;「AP 上限」已归属性值提升轴,见 1.2)。 - 原在册的「秘宝充能」「完美资格」两笔随 2026-10-18 两件裁削注销——`attune_charges` 账本本身仍为秘宝基础设施保留(迭代 11,主动件充能每冒险重置),本次只删奇物侧写它的入口。 +- 完美资格的豁免走**订阅式自有累加账**:授予段在 `seal_missed` 命中时累加豁免数,判定取「误标总数 − 豁免数」得有效数;**不改写误标账本身、不拦截事件**(迭代 31 卡② 契约 2/3)。 - 登记此节防止把凭证当成会持续生效的东西去结算。 #### 1.4 分类判据 diff --git a/design/gdd/ux/interaction-patterns.md b/design/gdd/ux/interaction-patterns.md index f8c7e79e..584fc018 100644 --- a/design/gdd/ux/interaction-patterns.md +++ b/design/gdd/ux/interaction-patterns.md @@ -87,7 +87,7 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab - 数据源:[战斗结算](../systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)步骤流(9 类行封闭协议(现行);公共字段 `type/source_class/origin_cell/round_index/display_name/value/highlight?`);**无来源行 = 断言失败** - 行模板:「{行为} {值} → {目标}(来源)」——来源标注(第 N 轮 · 安全格式);行文案最长 token = 来源标签(4 汉字封闭枚举),模板预留 40% 膨胀宽度 - 聚合纪律:未生效类行(奖励未生效——现行 9 类行协议唯一未生效型,2026-09-20 收敛)按聚合计数呈现(防逐行惩罚轰炸);衰减行聚合计数;效果行 value=单次贡献值、禁与 pool_value(池合成值)相加呈现;零值行可见不吞(免伤轮归因不断点) -- 高亮:highlight 字段 {flag_hit, clear_reward_h2, perfect_broken} → 金框强调;完美排雷 = 独立高光行 + 全屏喝彩级反馈 +- 高亮:highlight 字段 {flag_hit, clear_reward_h2, perfect_broken} → 金框强调;完美排雷 = 独立高光行 + 全屏喝彩级反馈。`perfect_broken` 的判据句读作「本板首次标错受检」,不等于完美资格已失——专长「完美保险」可在本场首次标错时豁免,实际资格按有效误标(误标总数 − 豁免数)判定 - 布局:固定槽高 + clip_contents;正文 ≥14px;数值暗底高对比;未生效类行带 icon/划线形状冗余 - 击杀标记呈现(H3 数据源 = 战斗结算流水击杀结果字段) diff --git a/design/gdd/术语表.md b/design/gdd/术语表.md index 7e816b21..5c080b48 100644 --- a/design/gdd/术语表.md +++ b/design/gdd/术语表.md @@ -11,7 +11,7 @@ | 安全格 | 没有惩罚的格子——挖开安全并获得其上信息与收益 | | 整图 | 单张棋盘(的整个范围)——原「整图」退役(2026-10-11 用户裁)。例:整图叠加层、整图作用域 | | 叠加层(整图叠加层) | 秘宝产生的信息的自持容器:按效果分类的格集,随图消亡、不回写棋盘(见[秘宝](systems/跨局循环/秘宝.md)) | -| 封印 / 控制 | 封印动作的机制名/玩家名:封印印记落在危险格上为「标中」(危险格被控制、化险为利),封错为「标空」(原「旗 / 控制」,2026-10-18 用户裁:「旗」概念不存在——动作=封印、印记=封印印记) | +| 封印 / 控制 | 封印动作的机制名/玩家名:封印印记落在危险格上为「标中」(危险格被控制、化险为利),封错为「标空」(原「旗 / 控制」,2026-10-18 用户裁:「旗」概念不存在——动作=封印、印记=封印印记);代码契约键与标识符统一用 `seal_*`(原 `flag_*` 全族换代),板面单字字形=「封」 | | 真视 | 直接告诉玩家某范围内哪些格是危险格的效果(秘宝承重契约:一次最多 3×3,见[秘宝](systems/跨局循环/秘宝.md)核心规则) | | 类型微光 | 棋盘上按格子类型显示的提示光效(视野参数控制其显示范围) | | 换图 / 弃图刷新 | 清完一图进入下一图 / 花储备放弃当前图重开一张(代价见[行动经济](systems/排雷循环/行动经济.md)) | @@ -81,6 +81,13 @@ 两类的判定与道具定义卡必答见[核心循环](01-核心循环.md)「结算目标分两类:总线与抽屉」节。 +## 战斗与效果 + +| 术语 | 定义 | +|---|---| +| `seal_missed` | 封印落空事件(原 `flag_missed` 换代):封印动作落在安全格上时发出,订阅面据此做限次与豁免判定(迭代 31 卡② 落地) | +| `forgive_seal_miss` | 本场首次封印落空豁免——专长「完美保险」的效果类型,`domain=battle` 首例;有效误标=误标总数 − 豁免数,豁免不改写误标账(迭代 31 卡② 落地) | + ## 开发流程 | 术语 | 定义 | @@ -113,11 +120,12 @@ 注:「注销」仅用于清单条目办结义(销号/销账的替换词);「结束登录状态」义仍按 STC 用「退出登录」。 -### B. 豁免条款(三类文本不改写) +### B. 豁免条款(四类文本不改写) 1. **历史文本**:git 提交说明、裁决记录中引用用户原话的句子——保留原用词,不按 A 表追改。 2. **对照性文本**:「退役词对照」表本身、「原 ××」式更名记载、禁令引举句——旧词在这些位置是内容本身,不是残留。 3. **玩家可见专名与机制词**:按「对外命名纪律」节与各系统文档现行用语使用(标中/踩雷等机制词在文档内部照常用)。 +4. **被检查的禁字不算使用**:守卫代码里作为检查对象的禁字字面量——`game/smoke/smoke_all.gd` 的 `contains("旗")` 检查项、`game/tests/unit/presentation/ui_font_asset_test.gd` 的字形集负探针、`game/data/tables/feats.tres` 头注的「desc 禁『雷/旗』字面」、`tools/doc_term_audit.py` 的退役词表定义行——不属换代范围:被检查的字不是对该字的使用,改写等于自毁守卫。术语清扫的复扫口径按 **game/ 全部文件类型、不排除任何扩展名**执行(迭代 31 卡① 实测:金币/插旗/雷格/惩罚格/`flag` 均 0 命中,残留仅为上述保留面)。 存量口径:A 表生效前已入库的正文不做强制清扫;文件后续被批次触碰时,顺带按 A 表换代。 @@ -135,6 +143,7 @@ | 金币 | GP(2026-10-18 用户裁:GP 是唯一正式命名,「金币」系 AI 噪音全库禁用) | | 插旗 | 封印(2026-10-18 用户裁:封印=正式动作名,全库统一,非比喻非「对外表达」别名) | | 旗(游戏概念语境) | 封印印记(2026-10-18 用户裁:「旗」概念不存在——封印动作落下的印记称封印印记) | +| flag_*(代码契约键/标识符) | seal_*(2026-10-18 用户裁全族换代;迭代 31 卡① 已清零) | ## 对外命名纪律(玩家可见命名,2026-10-11 用户令) From df4518d8789a95b4233255855ace1635dcb66a3a Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 15:28:38 +0800 Subject: [PATCH 17/59] =?UTF-8?q?chore(=E6=89=B9=E5=90=8E=E6=94=B6?= =?UTF-8?q?=E5=B0=BE):=20=E8=BF=AD=E4=BB=A3=2031=20=E4=BA=A7=E5=87=BA?= =?UTF-8?q?=E7=89=A9=E4=B8=8E=E4=B8=A4=E5=8D=A1=E9=80=80=E5=BD=B9=E2=80=94?= =?UTF-8?q?=E2=80=94=E5=90=B8=E6=94=B6=E5=8D=B3=E6=AD=BB=E5=88=A0=E9=99=A4?= =?UTF-8?q?=EF=BC=8C06/roadmap=20=E8=B4=A6=E9=9D=A2=E6=8D=A2=E4=BB=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 反哺点 14 条已于 7682559 落文(术语表 seal_* 契约键与效果词条、奇物完美保险指向、07 ㉙ 七项目检、美术件名与守卫例外条款、06 新候选) - 代拍板追认:13 项全部追认(卡① 1-6、卡② 7-13);待裁 A=甲——玩家面残留禁字另开小批、已登记 06;B=乙——perfect_broken 判据句改文档措辞、代码零动 - 实现报告 §六-1 未闭项迁 06「计数器寿命域未统一」:domain=battle/adv​enture 寿命判据无法由单测 rig 变异证红,闭合时补 runner/MC 对照读数或确认不设机检 - 06 删除两条已完成条目(代码术语刷新批、凭证件裁削批·代码侧) - roadmap 迭代 31 行改「已完成(2026-10-19)」、两列改已退役保留字;当前位换代至迭代 1–31 全完成 - 代码术语审计报告的卡片指路句改指合回 commit 4f953ce8/3e076e22(卡片退役后不留死径) --- design/gdd/06-待办清单.md | 23 +- .../research/代码术语审计报告-2026-10-18.md | 4 +- reports/iter31-代拍板-2026-10-19.md | 44 --- reports/iter31-反哺点-2026-10-19.md | 67 ---- reports/iter31-实现报告-2026-10-19.md | 94 ----- reports/需求卡片-代码术语刷新批-2026-10-18.md | 330 ------------------ reports/需求卡片-凭证件裁削批-2026-10-18.md | 216 ------------ roadmap.md | 6 +- 8 files changed, 7 insertions(+), 777 deletions(-) delete mode 100644 reports/iter31-代拍板-2026-10-19.md delete mode 100644 reports/iter31-反哺点-2026-10-19.md delete mode 100644 reports/iter31-实现报告-2026-10-19.md delete mode 100644 reports/需求卡片-代码术语刷新批-2026-10-18.md delete mode 100644 reports/需求卡片-凭证件裁削批-2026-10-18.md diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index ea7dc883..4479afd8 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -555,17 +555,6 @@ **状态**:文档设计已闭合(design/research/需求澄清-营地交互重做-2026-10-18.md v1.0)+待美术设计+已写卡(reports/需求卡片-存档制数据层改造批-2026-10-18.md)+已写卡(reports/需求卡片-主菜单三入口化批-2026-10-18.md)+已写卡(reports/需求卡片-选档界面新建批-2026-10-18.md)+已写卡(reports/需求卡片-营地场景图新建批-2026-10-18.md)+已写卡(reports/需求卡片-ESC浮窗与营地顶栏批-2026-10-18.md) -#### 代码术语刷新批——禁用词全库清扫+flag→seal 标识符重命名(2026-10-18 登记,来源=会话提及,设计面=工程直入) - -**现状**:2026-10-18 用户裁定三组术语刷新(记忆 `project-terminology-rulings-20261018.md`):①GP 是唯一正式命名,「金币」系 AI 噪音全库禁用;②「插旗」全库禁用,正式动作名=封印,「旗」概念不存在;③代码英文标识符 flag_* 全换 seal_*。另「雷格」「惩罚格」2026-10-11 已裁退役→危险格,代码域尚未执行。审计报告(`design/research/代码术语审计报告-2026-10-18.md`)实查:game/ 代码域实测读数(2026-10-18 需求卡片 v1.4 复核;口径=区分大小写逐处计数,命令见卡片 §2):含 `flag` 的文件 57 个(.gd 53 + .tres 4)共 617 处,剔除 `size_flags_*` 70 处(19 个文件)与 `_fatal_flag` 4 处后**净待改 543 处/42 个文件**;中文禁用词 金币 39 处、插旗 62 处、雷格 75 处、惩罚格 1 处、「旗」含复合词共 376 处。涉及核心逻辑(minesweeper_rules.gd 净 59、battle_orchestrator.gd 33、grant_segment.gd 38)、数据表(feats.tres 15、settlement.tres、action_economy.tres、reward.tres、treasure_items.tres)、呈现层(board_view.gd 23、battle_end_overlay.gd 11、shop_overlay_view.gd、legend_overlay.gd)与冒烟测试(smoke_all.gd 单文件净 156 处=全集 29%)。订正说明:审计报告原记「game/ 约 757 处(flag_ 314 处/29 个 .gd;金币 116/插旗 210/雷格 109)」在现行代码上两种口径都复现不出:中文三词的读数属全库面(全库实测 金币 381/插旗 600/雷格 394 处),与本条的 game/ 范围混记;flag 侧则低估约一倍。逐文件读数以需求卡片 §2 为准。文档面(design/)由另批处理,本条只覆盖 game/ 代码域。 - -**归属**:全工程(排雷循环/战斗循环/冒险循环/呈现层/数据表/冒烟测试均触及;主责=术语表裁定执行) - -**状态**:已写卡(reports/需求卡片-代码术语刷新批-2026-10-18.md)+已编迭代 31 - - ---- - #### 需求卡片入库纪律未登记——502 批遗留的悬空待办(2026-10-18 登记,来源=批次移交,设计面=反哺点) **现状**:2026-10-16 迭代 29 编入批(提交 `21c83f5`)认定「需求卡片写进了 roadmap 却没在 06 登记」属流程漏洞,需要补一条卡片入库纪律。该条至今在 06 清单内查无(2026-10-17 与 2026-10-18 两次全文检索零命中)。唯一记过它的地方是根目录状态文件未决面第 31 行,该文件已于 2026-10-18 用户裁废除,故改记本条防遗忘。 @@ -642,22 +631,14 @@ **现状**:效果的「寿命/作用域」现由三套互不同属的机制拼成,无统一枚举——①`domain` 键仅作用于计数器,只有 `battle`(缺省,每战清零)/`adventure`(跨战持久)两值;②`reset_at: round_start` 表达回合级重置(`feats.tres` 用 4 处);③「按关重置」是**硬编码名单**(`adventure_runner.gd:873-877` 按关清零 `tree_*_used`),不在任何词表内;④**效果自身(非计数器)的寿命没有任何字段**——`effect_engine.gd:32` 的「封印桩本轮/石肤本场」是拿 cap 参数凑的注释,机器不可读。另有名实不符:`domain=adventure` 实际承担「按关重置」语义(代码现状即证:`effect_engine.gd` 词表无寿命字段)。`effect_engine.gd:119-121` 自称「生命周期四态」(跨战持久/按关重置/新冒险清零/断点保留),却未按枚举落地。**后果**:任何带寿命权重的核算(期望收益/强度摊销/「每 X 一次」折算)无法在数据层进行,须逐条读注释或读清除侧代码。**用户已裁:本批不动寿命域**,完美保险按现役 `domain=battle` 落地,此项仅登记、不入本批改动面。 +**证据面缺口(迭代 31 卡② 移交)**:`domain=battle` 每战清零与 `domain=adventure` 跨战持久这一对判据,现无法由单元测试 rig 变异证红(`feat_vouchers_test` 的变异②只钉住事件发射时机,未覆盖寿命域)。闭合此项时须在 runner/MC 面补一次「adventure 域计数器跨战持久 vs battle 域清零」的对照读数,或在文档批确认该判据只由代码注释与装载面约束、不设机检。 + **归属**:architecture.md 与 game/core/effect_engine.gd(待立独立批) **状态**:待裁决(是否统一寿命域口径) --- -#### 凭证件裁削批·代码侧迁移(2026-10-18 登记,来源=会话提及,设计面=文档轨) - -**现状**:GDD 侧已随 2026-10-18 文档批定稿(见 `奇物.md` v3.18),**代码零改动**。待做五件事——①`CURIO_KINDS` 移除 attune_battery/perfect_insurance 两枚及配套配额字段、件值字段、分发表分支;②`TIER_QUOTAS` rare 9→7、总量 104→102(**结构锚须重裁**——用户已裁「净删」,不接受转给别件;连带 rare 档品种 5→3,仅剩 ap/rap/time_sand);③`adventure_runner.gd` 清 `_pending_insurance`/`_battery_pending`/`choose_battery_target`/`battery_pending()`/断点存档键(🔴 `run_ledger.attune_charges` 账本与 `_seed_attune_charges` **禁删**——迭代 11 秘宝基础设施);④`feats.tres` 增完美保险行(rarity 取 rare、desc=「本场首次封印落空,不计入完美封印判定」、triggers 走 on=flag_missed + 每战限次),前置依赖**效果引擎 `EFFECT_KINDS` 扩签一种**(该行将成为 feats.tres 首例 `domain=battle`;候选名 forgive_flag_miss 已作废,2026-10-18 用户补裁效果类型名=**forgive_seal_miss**(随卡① flag→seal 命名接续,见需求卡片 v1.1 顶部通则);⑤`grant_segment.gd` 硬编码 `_fx_insurance` 改订阅式——**按用户指定做法**:新增自有累加计数,判定时取「误标总数 − 豁免数」得有效数,**不改写既有 `_perfect_hit_false`、不拦截事件**(原方案的回退式与拦截式均已否决)。测试面 `feat_vouchers_test.gd` V9/V16 同步。玩家面术语统一用「完美封印」、不用「完美排雷」(命名纪律见奇物.md v3.15)。 - -**归属**:game/ 代码与数据表(走独立 worktree 批) - -**状态**:文档设计已闭合(design/gdd/systems/冒险循环/奇物.md v3.18)+已写卡(reports/需求卡片-凭证件裁削批-2026-10-18.md)+已编迭代 31 - ---- - #### 2026-10-19 定名传导遗留二项(2026-10-19 登记,来源=会话提及,设计面=文档轨) **现状**:2026-10-19「系统资源/补给」定名批(`42d64ec2`/`17ef0180`)遗留两件文档面未结——①`design/gdd/systems/战斗循环/增益状态.md` 用「账/账本」指战斗内状态容器(:10「增益状态就是这本账」、:44「增益减益同账本」、:14「容器只记账」)。经用户确认它与「系统资源」**不是同一个东西**(前者是战斗内状态实例容器,后者是玩家可增减的数值容器),但用词冲突;是否改名(候选方向:容器/状态池)与连带指路句范围待用户裁。②`design/art/art-bible.md:198`(奖励金配色行「金币/宝箱/蜡封」)、`:211`(语义物件「金币=收益金」)与 `design/art/art-assets-checklist.md:105`(九家族图标名)应换代 GP,`design/registry/entities.yaml:623/:629/:637` 三处「金币」同批——均已在分支 `gpsweep-20261019`(`c5d50192`)改完但**未合回 master**,主区现值仍是旧文;合并动作归用户另会话,本批不代做。 diff --git a/design/research/代码术语审计报告-2026-10-18.md b/design/research/代码术语审计报告-2026-10-18.md index 5f59a0ec..b04e3117 100644 --- a/design/research/代码术语审计报告-2026-10-18.md +++ b/design/research/代码术语审计报告-2026-10-18.md @@ -34,7 +34,7 @@ 注:「封印」现有 170 处命中(46 文件),其中大部分是正确用法(封印=正式术语),但部分语境把它当「比喻」或「对外表达」描述,需修正措辞。 -**读数订正(2026-10-18 需求卡片 v1.4 实测,本表数字保留作历史读数不作施工依据)**:上表的 game/ 侧数字用现行代码复现不出。同一命令口径实测(`game/` 内、区分大小写逐处计数):含 `flag` 的 .gd 53 个文件 595 处 + .tres 4 个文件 22 处,剔除 `size_flags_*`(70 处/19 文件)与 `_fatal_flag`(4 处)后**净 543 处/42 个文件**;「金币」39 处、「插旗」62 处、「雷格」75 处、「惩罚格」1 处、「旗」含复合词 376 处。两处口径错误:①中文三词用的是**全库**读数(全库实测 金币 381/插旗 600/雷格 394 处),被记进了 game/ 范围行;②flag 侧低估约一倍(原记 270+22+22=314)。施工判据以 [需求卡片-代码术语刷新批](../reports/需求卡片-代码术语刷新批-2026-10-18.md) §2 的复现命令为准。 +**读数订正(2026-10-18 需求卡片 v1.4 实测,本表数字保留作历史读数不作施工依据)**:上表的 game/ 侧数字用现行代码复现不出。同一命令口径实测(`game/` 内、区分大小写逐处计数):含 `flag` 的 .gd 53 个文件 595 处 + .tres 4 个文件 22 处,剔除 `size_flags_*`(70 处/19 文件)与 `_fatal_flag`(4 处)后**净 543 处/42 个文件**;「金币」39 处、「插旗」62 处、「雷格」75 处、「惩罚格」1 处、「旗」含复合词 376 处。两处口径错误:①中文三词用的是**全库**读数(全库实测 金币 381/插旗 600/雷格 394 处),被记进了 game/ 范围行;②flag 侧低估约一倍(原记 270+22+22=314)。施工判据见需求卡片 §2 的复现命令(卡片已随迭代 31 实现批退役,git 历史可考;合回 `4f953ce8`)。 --- @@ -119,4 +119,4 @@ design/research/(提案、需求卡片)、design/qa/(审查报告)、des ## 6. 建议拆批 -见同目录需求卡片:`reports/需求卡片-代码术语刷新批-2026-10-18.md` +拆批已由迭代 31 执行(卡① 代码术语刷新+卡② 凭证件裁削,合回 `4f953ce8`/`3e076e22`);对应需求卡片已随实现批退役,git 历史可考。 diff --git a/reports/iter31-代拍板-2026-10-19.md b/reports/iter31-代拍板-2026-10-19.md deleted file mode 100644 index 82dadef8..00000000 --- a/reports/iter31-代拍板-2026-10-19.md +++ /dev/null @@ -1,44 +0,0 @@ -# 迭代 31 代拍板追认单(2026-10-19) - -- 批次:迭代 31 卡①「代码术语刷新批」(卡片 v1.4)+卡②「凭证件裁削批·代码侧」(卡片 v1.1),串行同迭代 -- 分支/worktree:`iter31-c1-term-20261019`/`g-plan2-iter31-c1-term`;`iter31-c2-curio-20261019`/`g-plan2-iter31-c2-curio` -- 口径:授权发生在卡片审问阶段(Q1–Q8/D1–D3),本单只登记**实现段超出卡片明列范围**的代拍板项,等你追认或推翻。 - -## 一、开工前你已裁的两项(不是代拍板,是裁决留痕) - -| # | 事项 | 你的裁定 | 落法 | -|---|---|---|---| -| R-1 | 素材实体名 `assets/art/board/flag_seal.png` 卡住卡① 的 V1「flag 零命中」(代码两处 res:// 字符串) | **甲:现在改素材名** | 改名 `seal_mark.png`;代码 2 处+`COL_FLAG`/`CURSOR_FLAG` 常量+闸件四处(`tools/run_all_gates.sh`/`render_gate.sh`/`golden_baseline_refresh.sh`/`path_check.py`)随批;盘上素材改名+导入重刷(素材不入 git);主区与两 worktree 三份同态 | -| R-2 | 卡① V7 对拍锚(`anchor.json` 的 jsonl 面是 sha256 清单,手改键名与摘要面不兼容) | **甲:重跑+重锚+改前改后 diff** | 卡① 重锚一次(三变体 120 局全跑),卡② 再重锚一次;改前原始面另起临时 worktree(`g-plan2-iter31-oldface`,检出 ed2dfaf6)实跑 dump 取证 | - -## 二、实现段代拍板清单(超卡片明列范围) - -### 卡① - -| # | 决定 | 依据与影响面 | -|---|---|---| -| 1 | 板面单字槽字形 `"旗"` → `"封"`(`board_view.gd:752` 赋值+`:785` 比较,消费面共 4 处:`board_view`/`ui_click_probe:556`/`ui_input_probe:217`) | 术语裁定「旗概念不存在」+字形槽是单字位;选「封」而非「封印」为保位宽与 golden 稳定。字体在册字形含「封」(`ui_font_asset_test` 原断言面即攻/雷/旗/封) | -| 2 | 大写常量 `COL_FLAG`→`COL_SEAL`、`CURSOR_FLAG`→`CURSOR_SEAL` | 卡片 §2 计数口径是小写 `flag`,未列大写形态;V1 精神是全族换代。零行为(纯标识符) | -| 3 | **守卫的禁字面量不换代**:`smoke_all.gd:1319` 的 `contains("旗")`、`ui_font_asset_test.gd:19` 的 `has_char("旗")` 保持原字 | 被检查的字不是对该字的使用;改写等于把「对外命名纪律」守卫自毁(禁「旗」变成禁「封印」)。卡片 §2 只订正了 `ui_assembler` 注释一处,未涵盖检查面。与卡片「术语表对照行不在本卡范围」同口径 | -| 4 | `game/README.md` 历史批注里的英文标识符(`_do_flag_place`/`flag_hit`/`minesweeper_flags` 等)随批换代 | 卡片 §5 只写「雷格/插旗随批替换」,而完成定义是 game/ 全局 grep 零命中;README 属本批直改文件。历史叙述的指称对象已改名,留旧名即失真 | -| 5 | 旧锚 `anchor.json` 的 RUNSUM 文本随代码同批改名,随后重锚(不再手改) | R-2 甲案;重锚后手改面作废 | -| 6 | `ui_assembler.gd:203` 注释按卡片 v1.4 订正句改写为「0=不设最小宽度」 | 卡片明列(非代拍板,登记免漏) | - -### 卡② - -| # | 决定 | 依据与影响面 | -|---|---|---| -| 7 | 完美保险专长**单行落表**(代拍板 3 的选型):`when counter(insurance_used) lt 1` 承载「本场首次」,`do` 自带 `counter_id`+`value` 由授予段消费点落账 | 卡片预设的「双行(forgive+counter_add)」实测不成立——效果引擎 `dispatch()` 只收集命中、**不代执行计数器**,counter_add 须由消费段显式调用;双行会在同一次 dispatch 内双双放行(第二次标错仍被豁免)。改单行后限次真生效(变异 `lt 1→lt 99` 证红)。DO_KEYS 的 `cap` 语义核不出「本 effect 累计上限」,故未走 cap 省行路线 | -| 8 | 豁免归因行 `source_class` 取 `"seal_miss"` | 旧代码 `_emit_row("insurance_used", "", …)` 空来源会触发行来源断言(`battle_orchestrator._assert_row_source`);旧路径因呈现层零接线从未真正走到,属**存量潜伏缺陷**。新订阅面一旦执行即红,故补真实来源(指回当格,满足「棋盘来源行必须指回真实格」);行型仍用在册 `insurance_used`,零新增行型 | -| 9 | `level_runner` 的 `voucher_insurance` 注入通道整链拆除(`set_voucher_grants` 降为两参) | 卡片 §2 落点表未列 `level_runner`(:478/:484/:646/:649/:652),但它是「战首注入链」的实际承载面;不拆即留死通道+参数空转。签名改动波及 `adventure_runner:920` 与 `smoke_all` 四处 rig | -| 10 | 卡② 新测试全部并入 `feat_vouchers_test.gd`(39 项),不新建套件 | 卡片代拍板 4(避免套件数膨胀);`run_all.gd` 登记面零改动(34 套不变) | -| 11 | 谓词抽成 `battle_orchestrator.perfect_sweep_earned()` 单点 | R2「真值表断言」需要可调用面;抽函数是零行为变化的取法(原式内联在清图奖励段),并使「漏减豁免」变异可证红 | -| 12 | 完美资格**归因行**的 `hl="perfect_broken"` 判据保持原样(仍按 `_perfect_hit_false == 1` 落,先于 `seal_missed` 发射) | 卡片契约 3 明令发射时机不得动;若把归因改到豁免之后再算,就得挪发射点或新增纠正行型(超范围)。后果:首次标错那一行仍带「完美已破」归因锚,而实际完美资格可能已被豁免保住——**文案层不一致,已列反哺点等你裁** | -| 13 | 断点兼容按「旧档多键不报错」验,不做迁移 | 卡片 L2 口径+卡① Q4 同源(Alpha 可作废) | - -## 三、需你裁决的两项(本单唯一待裁面) - -| # | 待裁点 | 两种读法 | 建议 | -|---|---|---|---| -| A | 玩家面残留禁字:`legend_overlay.gd:11` 图例行含「插错可左键直接挖开」「危险格吃**挖雷惩罚**」(v3.15 命名纪律:玩家面禁「雷」「插旗」) | 甲:本批已合回,另开小批清这两处文案;乙:视为卡① N2 未尽面,退回补做 | **甲**——「插错/挖雷」不属卡① 四个门禁词(金币/插旗/雷格/惩罚格),批内自扩判据=越权;已登记 06 候选 | -| B | 卡② 反哺:完美资格归因锚与豁免后实际态的文案层不一致(见代拍板 12) | 甲:维持现状(归因锚按「首次标错」语义);乙:文档批把 `perfect_broken` 的定义改写为「首次标错受检」;丙:改判据需动发射时机=需重开设计 | **乙**(改文档措辞即可自洽,代码零动) | diff --git a/reports/iter31-反哺点-2026-10-19.md b/reports/iter31-反哺点-2026-10-19.md deleted file mode 100644 index ce991abf..00000000 --- a/reports/iter31-反哺点-2026-10-19.md +++ /dev/null @@ -1,67 +0,0 @@ -# 迭代 31 反哺点清单(2026-10-19) - -- 口径:本批是代码实现批,禁写 `design/` 与根规则文件。下列每条写清「哪个文件哪一节/改成什么/依据」,由你在会话中裁决后归**文档批**落笔;落笔后本条即可删(`reports/README.md` 生命周期同口径)。 -- 依据批次:卡①「代码术语刷新批」v1.4(`reports/需求卡片-代码术语刷新批-2026-10-18.md`)+卡②「凭证件裁削批·代码侧」v1.1。 - -## 一、06-待办清单(`design/gdd/06-待办清单.md`) - -| # | 条目 | 改成什么 | 依据 | -|---|---|---|---| -| 1 | 「代码术语刷新批——禁用词全库清扫+flag→seal 标识符重命名」状态行(:550 段) | 由「已写卡+已编迭代 31」推进为「已完成(迭代 31 卡①,合并 `<卡① merge commit>`,2026-10-19)」 | 卡① §5 首行;合回 commit 见实现报告 §一 | -| 2 | 「凭证件裁削批·代码侧迁移」状态行(:643 段) | 推进为「已完成(迭代 31 卡②,合并 `<卡② merge commit>`,2026-10-19)」 | 卡② §5 末行 | -| 3 | 新增候选条目(可选) | 「玩家面残留禁字词清扫——图例/呈现文案两处」(见本清单 §六-A) | 实现期实测发现 | - -## 二、术语表(`design/gdd/术语表.md`) - -| # | 节 | 改成什么 | 依据 | -|---|---|---|---| -| 4 | 「旗/控制」相关对照行 | 对照行代号换代:`flag_*` 契约键全部改记 `seal_*`;动作名=**封印**、呈现名=**封印印记**、单字字形=**封** | 卡① N1/N2+代拍板 1(字形取「封」) | -| 5 | 效果类型/事件词条 | 新增 `forgive_seal_miss`(本场首次封印落空豁免,domain=battle 首例)与 `seal_missed`(原 `flag_missed` 换代) | 卡② §5 末行;实装点 `effect_engine.gd:44`、`feats.tres` 第 30 行 | -| 6 | 显式补一条「禁字守卫面例外」 | 注明:守卫代码里的**被检查禁字**(`smoke_all.gd:1319` 的「旗」、`ui_font_asset_test.gd:19` 的「旗」)不属换代范围——被检查的字不是对该字的使用 | 卡① 完成定义与 V4 判据的边界,实现期已按此执行(代拍板 3),需成文防后来者误清 | - - -## 三、GDD 奇物篇(`design/gdd/systems/冒险循环/奇物.md` v3.18) - -| # | 位置 | 改成什么 | 依据 | -|---|---|---|---| -| 11 | v3.18 登记⑤与件表注「归独立批」指针 | 销号:代码侧已落地(删件/迁出/配额净删/引擎扩签/订阅式改写五项全落),指针改指本迭代合回 commit | 卡② §5 首行 | -| 12 | §1.3 异质性账清单 | 「完美资格」账的写法可补一句「豁免走订阅式自有累加账,不改写误标账」 | 卡② 契约 2 落地形态(实现无反哺新设计,仅既有陈述的换代) | - -## 四、07-体验验证清单(`design/gdd/07-体验验证清单.md`) - -| # | 改成什么 | 依据 | -|---|---|---| -| 13 | 新增目检项三条(卡① 玩家面换代):①商店界面显示「GP」不再出现「金币」;②图例/HUD 显示「封印/封印印记」不再出现「插旗/旗」;③结算明细来源显示「封印命中/封印未中」不再出现「标中旗/标旗未中」 | 卡① §7 正常流程体验三项 | -| 14 | 新增目检项两条(卡②):R5 完美保险专长卡面文案(desc 读作「本场首次封印落空,不计入完美封印判定」、零「雷」字);R6 三选一再不出现同调电池/完美保险,稀有档仅剩 ap/rap/time_sand 三种 | 卡② §7.1 R5/R6(本批禁写 07,先记实现报告总清单) | -| 15 | 注销两件奇物在 07 的既有观测项(若在册) | 卡② §5 第三行 | - -## 五、待你裁后才好落文的三项(本清单唯一非换代面) - -| # | 事项 | 建议落点 | -|---|---|---| -| A | **玩家可见文本残留「雷/排雷/插」全表五处**(v3.15 命名纪律:玩家面禁「雷」,危险格对外风味=地下城陷阱/怪物巢穴):① `legend_overlay.gd:11` 图例行「插错可左键直接挖开…危险格吃**挖雷**惩罚」;② `status_slot_row.gd:42` 与 `settlement.tres:14` 明细来源名 `"mine_hit": "踩雷"`;③ `battle_log_view.gd:194` 战斗日志「本板**完美排雷**已破——归因此封印」;④ `board_fx_view.gd:102` 横幅「**完美排雷** ×2」;⑤ `board_view.gd:737` 已开危险格单字字形 `glyph = "雷"`(**注意:改字形会动 golden 基线,须同步重制 C 档基准**)。 | 归 06 新条目+文案小批一次清完;①-④ 纯文案零风险,⑤ 需连带渲染基线换代。开发注记面(`ui_kit.gd:37` 常量名 RED_MINE 与其注释)属内部语,按纪律保留 | -| B | 完美资格**归因锚**文案层不一致:首次标错那一行仍标 `perfect_broken`,而该次可能已被豁免 | 建议只改文档措辞(判据句读作「首次标错受检」),代码零动(详见代拍板单 §三-B) | -| C | 闸件面:`screen_flow_probe` 因 `user://save.json` 全 worktree 共用而假红(本次实测:主区基线与卡① worktree 首跑均红,把存档移开即全绿)。`run_all_gates.sh`/`probe_gate.sh` 是否应自带「跑批期隔离 user 目录」或「探针前预清档」 | 归工具批候选,登记 06(本批只按既有手册处置=人工移档) | - -## 六、美术与素材面(卡① R-1 甲案的文档欠账) - -| # | 文件 | 改成什么 | 依据 | -|---|---|---|---| -| 16 | `design/art/asset-path-map.md:30`(board/ 行现役清单) | 件名 `flag_seal.png` → **`seal_mark.png`**;类目措辞「砖面/旗印记…封印旗」→「砖面/封印印记…」 | 素材已实改名(盘上+两 worktree+主区三处同态),文档现役清单落后于代码=B3 路径核对器的声明面失实风险 | -| 17 | `design/art/art-bible.md`(board 域挂点条款、v3.9 P2 ②句中的 `flag_seal`) | 同件名换代+规格注记(32×32 封印印记可选件) | 素材命名唯一事实源在 art-bible,须与盘上同步;本批禁写 | -| 18 | `tools/path_check.py`/`render_gate.sh`/`run_all_gates.sh`/`golden_baseline_refresh.sh` | **已随卡① 改**(新件名),无需文档批再动 | 你已裁甲案授权本批改这四处 | - -## 七、roadmap(根规则文件 `roadmap.md`,本批禁写) - -| # | 位置 | 改成什么 | 依据 | -|---|---|---|---| -| 19 | 迭代 31 行(:67)状态列 | 「待开工」→「已完成(2026-10-19)」;产出物列填 `reports/iter31-实现报告-2026-10-19.md` | 卡② §5 第四行;两卡合回 commit `4f953ce8`(卡①)+`3e076e22`(卡②)+`afe91cb5`(产出物) | -| 20 | 顶部「当前位」三行(:8-9) | 「迭代位」改记迭代 1–31 全部已完成或已终止、迭代 32 待编排;「下一步」改记 06 在册候选(营地交互重做五卡待编迭代、迭代 30 原卡②③待重新立卡、本批新增 06 候选见 §六-A/§六-C) | 卡② §5 第四行+roadmap 自订纪律(当前位只答「现在该做什么」,三行内换代) | - -## 八、门禁词全类型复扫结果与保留面(本批判据的成文补充) - -| # | 事项 | 内容 | -|---|---|---| -| 21 | V1/V4 复扫口径升级 | 原口径按 `.gd/.tres/.md/.json` 四类扩展名扫;已按**game/ 全部文件类型不排除任何扩展名**重扫:金币/插旗/雷格/惩罚格 **0 命中**,`flag`(不分大小写、减两类假阳性后)**0 命中**,「旗」字命中仅存在于下表保留面 | -| 22 | 保留的「旗/雷」**被检查字面量**(六处,改写=自毁守卫) | `smoke_all.gd:1319` 的 `contains("旗")` 与 `:1321` 检查项描述、`ui_font_asset_test.gd:18-19` 的字形集断言(含退役字「旗」的字体覆盖面负探针)、`feats.tres:10-11` 头注「desc 禁『雷/旗』字面」与命名纪律对照句;`tools/doc_term_audit.py:34,60-64` 的退役词表定义行(同族,属工具侧词表声明面,卡① §4 归文档批/工具批) | -| 23 | 建议成文口径 | 术语类清扫的判据应写成「**被检查的禁字不算使用**」——建议在 doc-conventions 或术语表「对外命名纪律」节补一条,防止后来者把守卫字面量当残留清掉(本批已按此执行并留代拍板 3) | diff --git a/reports/iter31-实现报告-2026-10-19.md b/reports/iter31-实现报告-2026-10-19.md deleted file mode 100644 index 5d2e0856..00000000 --- a/reports/iter31-实现报告-2026-10-19.md +++ /dev/null @@ -1,94 +0,0 @@ -# 迭代 31 实现报告(卡① 代码术语刷新批 + 卡② 凭证件裁削批·代码侧) - -- 卡片:`reports/需求卡片-代码术语刷新批-2026-10-18.md` **v1.4**、`reports/需求卡片-凭证件裁削批-2026-10-18.md` **v1.1**(roadmap 迭代 31 行两卡,串行:卡①→卡②) -- 分支/worktree:卡① `iter31-c1-term-20261019`/`g-plan2-iter31-c1-term`;卡② `iter31-c2-curio-20261019`/`g-plan2-iter31-c2-curio`;取证专用临时区 `g-plan2-iter31-oldface`(检出 ed2dfaf6,跑完即删,不入库) -- 闸口径:两卡均触 `game/` → 代码域;卡① 另触 `tools/` 四处(素材名随批,你裁甲案授权)→ 合回前跑**全量档**(代码+文档两域),卡② 触 `game/`+`reports/` → 同按两域 -- 开工门:U0=本会话 `/iter 31`;开工检查的自洽扫描核出两处卡片缺口,均由你当场裁(见代拍板单 §一 R-1/R-2),零待裁点前提下才动工 -- 完成日 2026-10-19 - -## 一、各任务卡状态 - -### 卡① 代码术语刷新批 - -| 卡 | 状态 | 要点与取证 | -|---|---|---| -| T0 基线 | ✅ | 主区 `ed2dfaf6` 全量代码域跑批:冒烟 **1151 项 0 失败**/单元 **34 套全绿**/探针 --click 与 --full 仅 `screen_flow_probe` 红(后证=`user://save.json` 全 worktree 共用污染,移开存档即全绿,见 §五-3)/渲染闸·静态扫描·熵增闸绿 | -| T1 .tres 重命名 | ✅ | `action_economy.tres`/`settlement.tres`/`feats.tres`/`treasure_items.tres`/`reward.tres`/`status_effects.tres` 键名与显示名全换代(`seal_place_ap_cost`/`seal_hit_premium`/`"seal_hit": "封印命中"`/`"seal_miss": "封印未中"`/`echo_seals`/`smith_seals`/`seal_burst`/`dug_under_seal`/`seal_range_free`/`"GP 袋"`) | -| T2 schema 同步 | ✅ | `action_economy_table.gd`/`settlement_table.gd`/`treasure_item_table.gd`/`reward_table.gd` 与 T1 同批改(契约:键名与读取面禁分两批);卡片未列的 `flag_pull_ap_cost` 一并换代(同批同步=契约面) | -| T3 核心层 | ✅ | `effect_engine.gd` EVENTS/MINE_EVENTS/FACTS 三词表换代(含卡片 v1.4 补的 `seals_count`/`dug_under_seal` 全链);`minesweeper_rules.gd` signal `flag_judged`→`seal_judged`+`battle_orchestrator` 连接与回调同名;`grant_segment`/`action_economy`/`config_db_cross_validator` 等同批 | -| T4 呈现层 | ✅ | 18 个文件;UI 字符串「金币→GP」「插旗→封印」「此格已有封印印记」(按卡① T4.9 措辞);单字字形按代拍板 1 取「封」 | -| T5 冒烟与测试 | ✅ | 24 条明列落点+grep 兜网全部收敛;卡片 v1.4 补列的 5 文件(`screen_flow_probe`/`effect_words_t1_test`/`ui_probe`/`type_glow_shot_probe`/`fx_probe`)均改;净命中文件数 42→0(V1 判据口径) | -| T6 README+锚+验证 | ✅ | `game/README.md` 换代(含英文标识符历史注记,代拍板 4);`anchor.json` 走你裁的重锚路线;V1/V2/V3/V4/V5/V6/V7 全过(读数见 §二) | - -### 卡② 凭证件裁削批·代码侧 - -| 卡 | 状态 | 要点与取证 | -|---|---|---| -| T0 开工基线 | ✅ | 基于卡① 合回后的 master 建区;先跑 `git merge` 取卡① 成果并按卡片通则复核标识符与行号(卡片 §2 旧名 `flag_*` 全部按 `seal_*` 现形态执行) | -| T1 电池表侧删 | ✅ | `CURIO_KINDS` 摘 kind;`curio_quota/value/cap_attune_battery*` 三字段+三处分发表分支删净;表头注记换代 | -| T2 电池 runner 侧删 | ✅ | `_battery_pending`、断点回填与断点键、开局重置、`_apply_curio_pick` 路由分支、`choose_battery_target()`、`battery_pending()` 全清;`attune_charges` 账本与 `_seed_attune_charges()` **零改动**(契约 1) | -| T3 完美保险出池 | ✅ | kind/三字段/三处分发表分支删;`_pending_insurance` 与路由分支删;**注入链整链拆除**含卡片未列的 `level_runner`(`voucher_insurance` enc 键、`_voucher_insurance`、`set_voucher_grants` 降为两参)与 `battle_orchestrator._fx_insurance` 及注入点 | -| T4 引擎扩签+两账相减 | ✅ | `EFFECT_KINDS` 31→32 增 `forgive_seal_miss`;消费点在 `grant_segment` 的 `seal_missed` 命中循环内(新增 elif 分支,累加 `_perfect_forgiven` 并落 `insurance_used` 归因行,source_class=seal_miss);谓词抽成 `battle_orchestrator.perfect_sweep_earned()`(有效误标=误标−豁免);`_perfect_hit_false` 全程未被任何效果改写(契约 2);`seal_missed` 发射点与时机零改动(契约 3,变异②与「事件不吞」断言双向钉住) | -| T5 专长行落表 | ✅ | `feats.tres` 第 30 行 `perfect_insurance`/rarity rare/cap 省略/`on: "seal_missed"`/`kind: "forgive_seal_miss"`/`domain: "battle"` 显式写出(战斗域首例,行内+表头注双留痕);`FeatTable.validate()` 零违例;引擎装载后可派发(39 项验收组实测) | -| T6 配额重裁落地 | ✅ | `TIER_QUOTAS` rare 9→7、总量 104→102;`validate()` 硬断言过;`adventure.tres` 实例值核对(两件在本表无实例覆盖,零同步项);rare 档品种实测={ap, rap, time_sand} | -| T7 测试补齐 | ✅ | 并入 `feat_vouchers_test.gd`(代拍板 10):**39 项全绿**——出池词表/兑付反例/符号清零(`has_method` 编译级)/未知 kind 分发表兜底/账本保留/断点缺键与多键兼容/配额锚/专长行合法与 desc 零「雷」/限次一次/计数纯净/两账相减真值表(2−1、1−1、标中=0 三格)/事件不吞(守侧订阅对拍)/跨战清零;`forge_table_test` 词表闭集断言 31→32;变异验证见 §三 | -| T8 产出物+代码域闸 | ✅ | 本报告+代拍板追认单+反哺点清单三份落 `reports/`;合回前全量档回执见 §四 | - -## 二、改前/改后读数对照 - -### 卡①(纯重命名批——行为零变化的三层证词) - -| 面 | 改前(主区 ed2dfaf6 实跑) | 改后(卡① worktree 实跑) | 判读 | -|---|---|---|---| -| V1 `flag` 零命中 | 57 文件 617 处(净 543 处/42 文件) | **0**(豁免面仅 `size_flags_*` 与 `_fatal_flag`) | 过 | -| V4 四禁用词零命中 | 金币 39/插旗 62/雷格 75/惩罚格 1(另「旗」族 376) | **0**(`game/` 内 .gd/.tres/.md/.json 全域);「旗」字残留=0 | 过 | -| V2 冒烟 | 1151 项 0 失败 | 1151 项 0 失败 | 绿数一致 | -| V3 单元 | 34 套全绿 | 34 套全绿 | 一致 | -| V6/V7 对拍 | 改前=master 同代旧代码**实跑 dump**(`_parity_old`,三变体 120 局) | 改后=卡① 重锚(同 120 局) | **标签归一后 120 行真差异 0 行**;jsonl 事件流六面行数 **6/6 全同**(8051/43795/10579/40180/7060/43844),改前原始面含 `flag` 标签行 2175–10424/面,换代后仅标签名变、数值零漂移 | -| 锚的陈旧面(登记) | 合入前仓库里的 `anchor.json` 系 2026-10-15 冻结,与 10-18 的 master 已有 45/120 行漂移(历次代码批未重锚) | — | 该漂移**不属本批**;卡① 重锚把它一次性对齐(你的甲案口径) | - -### 卡②(裁断驱动的行为变化批——变化面须可解释) - -| 面 | 改前(卡① 合回后锚 `2c5cece4`) | 改后(卡② 重锚 `0170071d`) | 变化归因 | -|---|---|---|---| -| RUNSUM | 120 行 | 120 行,97 行差异 | 差异字段分布=`reward_events`×97、`relics`×78、`seal_*`×76、`taken/rounds/hero_dmg`… 全链派生自「稀有档候选集少两件」——三选一抽取序列改变→后续账全面位移;正是用户逐裁的预期效果面(非回归) | -| jsonl 行数 | 8051/43795/10579/40180/7060/43844 | 8945/39811/9620/38435/7499/45132 | 同因:牌库与豁免语义变化改变对局长度与事件数,方向不一(有增有减)=非单调劣化 | -| 完美保险 | 无玩家入口、`_fx_insurance` 恒 0、豁免行路径从未被执行 | 专长订阅式,每战首次标错豁免一次 | 39 项验收组+5 条变异证红 | - -## 三、变异验证记录(卡② §7.2 六条,最窄闸=`feat_vouchers` 套件) - -| 变异点 | 注入形态 | 结果 | 命中红项 | -|---|---|---|---| -| 两账相减漏减豁免 | `perfect_sweep_earned()` 改回 `_perfect_hit_false <= 0` | 红 ✅ | 「判定相减:误标 1 − 豁免 1 = 有效 0 且标中≥1 → 完美成立」 | -| 计数纯净(改回退式) | 消费点改 `oc._perfect_hit_false -= 1` | 红 ✅ | 「计数纯净:首次标错 _perfect_hit_false 落 1 未被回退改写(契约 2)」 | -| 限次 | 行 `when` 的 `lt 1` 改 `lt 99` | 红 ✅ | 「限次:第二次标错不获豁免(forgiven 恒 1)」 | -| 寿命域 | 行 `domain: battle` 改 `adventure` | **未红 ⚠️** | 本 rig 不可观测:`adventure` 域计数器在单测里由 `counters_seed({})` 起零,次战同样从 0 开始→与 `battle` 域表现相同。真正的差异面在 runner 的 `counters_export/seed` 跨战持久路径(需 MC 或 runner 级 rig)。**遗留读数义务**(见 §五-1) | -| 配额锚 | `rare: 7` 改回 `9` | 红 ✅ | 表加载失败→「数值表加载失败」(validate 硬断言在加载期即致命,符合「改总量=重裁」) | -| 电池出池 | kind 加回 `CURIO_KINDS` | 红 ✅ | 「出池词表:CURIO_KINDS 零两件」 | - -## 四、闸况与合回凭据 - -| 步骤 | 凭据 | -|---|---| -| 卡① 合回前重闸(全量档,两域) | worktree `g-plan2-iter31-c1-term` 回执 commit `2c5cece4`,domain=full,**all_green=true**,12 闸零新增红(含 05 渲染闸、11 对拍 check 绿、06/07/08/08c 文档四闸绿);主区合回 commit `4f953ce8` | -| 卡② 合回前重闸(全量档,两域) | worktree `g-plan2-iter31-c2-curio` 回执 commit `<待填>`,结果 `<待填>`;主区合回 commit `4f953ce8` | -| 合回后主区复跑 | `--editor --quit` 重刷类名缓存后 `run_all_gates.sh --code`:主区 `3e076e22` 复跑回执 **all_green=true**、无新增红;冒烟 1151 项 0 失败、单元 34 套全绿(卡② 合回后主区实态) | - -## 五、实机目检总清单(登记 07 的凭据面;真人检测只登记不阻塞) - -| # | 目检项 | 来源 | -|---|---|---| -| M1 | 商店界面货币显示「GP」,不再出现「金币」 | 卡① §7 | -| M2 | 图例/HUD 显示「封印/封印印记」,不再出现「插旗/旗」;板面单字字形现为「封」(代拍板 1) | 卡① §7 | -| M3 | 结算明细来源显示「封印命中/封印未中」 | 卡① §7 | -| M4 | 封印印记贴图(素材已改名 `seal_mark.png`)在 L1/L2/L3 三关均正常加载,非字形回退态 | 卡① R-1 甲案新增 | -| M5 | 完美保险专长卡面文案:「本场首次封印落空,不计入完美封印判定」,零「雷」字 | 卡② R5 | -| M6 | 三选一带不再出现同调电池/完美保险;稀有档仅剩 ap/rap/time_sand | 卡② R6 | -| M7 | 清图奖励的「完美第二份」在带完美保险专长时于首次标错后仍能拿到(订阅式豁免的实际观感) | 卡② R2 玩家面 | - -## 六、遗留读数义务与已知项 - -1. **卡② 寿命域变异不可由单测 rig 证红**(§三 第 4 行)——需 runner/MC 面补一次「adventure 域计数器跨战持久 vs battle 域清零」的对照读数,或在文档批确认该判据只由代码注释与装载面约束。未闭。 -2. **旧断点存档的 `battery_pending`/`echo_flags`/`smith_flags` 键**:Alpha 阶段按你裁定不做迁移;实机续玩旧档时该两族计数器归零,属预期。 -3. **`user://save.json` 全 worktree 共用导致探针假红**:本次实测把存档移开即全绿(六/七道闸均受影响)。已列反哺点 §六-C 归工具批候选。本批跑闸期间存档临时移开,收口时原样还原(备份件 `_save_json_backup_user_20261019.json`)。 -4. **卡片 §2 现状读数的两处不实**:卡① v1.4 已订正计数面;本批另实测发现卡片未列的落点共 8 处(`flag_pull_ap_cost`、大写 `COL_FLAG`/`CURSOR_FLAG`、`level_runner` 注入链、守卫禁字面量 2 处、README 英文历史注记、`smoke_all` 行数/牌库构成断言 4 处)——属卡片「发现未列落点按契约同步即可」口径,仍登记以便写卡段回看。 diff --git a/reports/需求卡片-代码术语刷新批-2026-10-18.md b/reports/需求卡片-代码术语刷新批-2026-10-18.md deleted file mode 100644 index 2f654c06..00000000 --- a/reports/需求卡片-代码术语刷新批-2026-10-18.md +++ /dev/null @@ -1,330 +0,0 @@ -# 需求卡片:代码术语刷新批(flag→seal+中文禁用词清扫) - -- 版本:**v1.4**(2026-10-18 卡片正确性复核批:§2 现状事实的命中数改为**可复现实测读数**——v1.x 沿用审计报告的计数在现行代码上无法复现,且总量低估约一倍、文件数少记 24 个;历史:v1.3 冲突修订批、v1.2 grilling Q4–Q8、v1.1 Q1–Q3) -- 来源: - - [06-待办清单](../design/gdd/06-待办清单.md)「代码术语刷新批——禁用词全库清扫+flag→seal 标识符重命名」(2026-10-18 登记,工程直入) - - 用户裁定(2026-10-18,记忆 `project-terminology-rulings-20261018.md`) - - 审计报告:[代码术语审计报告-2026-10-18](../design/research/代码术语审计报告-2026-10-18.md) -- 归属:全工程(排雷循环/战斗循环/冒险循环/呈现层/数据表/冒烟测试);术语权威=[术语表](../design/gdd/术语表.md) -- 排期:**已编入 roadmap 迭代 31**(2026-10-18 用户确认;卡片状态=已编入,开工门=U0) -- **设计前置声明**:本卡属**重构/工程债**类,凭 2026-10-18 用户裁定与审计报告代码级证据直接写卡,跳过设计轨。 -- **设计事实源**(req-card §2 三选一之③工程直入证据指认,2026-10-18 立规;v1.3 补声明):[代码术语审计报告-2026-10-18](../design/research/代码术语审计报告-2026-10-18.md)(已入库 HEAD)逐条 file:line + 06 条目「代码术语刷新批——禁用词全库清扫+flag→seal 标识符重命名(设计面=工程直入)」现状段。两处读数一致:`game/` 命中约 757 处(flag_ 270 处/29 个 .gd + 22 处 .tres;金币 116/插旗 210/雷格 109)。 - -## 1. 目标与完成定义 - -| 需求点 | 一句话 | -|---|---| -| **N1** | 代码标识符 flag_* 全族重命名为 seal_*(变量名、函数名、字典键、事件名、数据表字段、字符串值) | -| **N2** | .gd 注释与 UI 字符串中中文禁用词清扫:金币→GP、插旗→封印、雷格→危险格、惩罚格→危险格、旗(游戏概念)→封印印记 | -| **N3** | .tres 数据文件中中文禁用词清扫(display_name、desc、注释) | -| **N4** | game/README.md 同步 | - -**完成定义**:game/ 目录内全局搜索 `flag`(排除非游戏语境如 git flag)零命中;全局搜索「金币」「插旗」「雷格」「惩罚格」零命中(术语表对照行不在本卡范围);全量冒烟(smoke_all.gd)+单元测试(tests/run_all.gd)全绿,绿数与改前基线一致;`reports/` 三份产出物写齐(实现报告/代拍板追认单/反哺点清单)。 - -**文档面不在本卡完成定义内**(2026-10-17 req-card §6 改口径:代码实现批禁写 `design/` 整目录与根规则文件,唯一可写目录=`reports/`)——06 条目状态推进、术语表、entities.yaml、07 目检项一律列进 `reports/iter31-反哺点-<日期>.md`,由用户在会话中裁决后归文档批落文。 - -## 2. 现状事实(2026-10-18 代码级实查) - -### N1 · flag_* 标识符分布 - -**总量(v1.4 实测,2026-10-18,口径见下)**:`game/` 内含 `flag` 的文件 **57 个**(.gd 53 个 595 处 + .tres 4 个 22 处,合计 617 处);剔除假阳性 `size_flags_*` 70 处(19 个文件)与 `_fatal_flag` 4 处(1 个文件)后,**净待改 543 处、42 个文件**。 -复现命令(在 `game/` 目录):`grep -ro 'flag' --include=*.gd --include=*.tres . | wc -l`(总处数);净处数=逐文件 `grep -o 'flag'` 减 `grep -o 'size_flags[a-z_]*'` 减 `grep -o '_fatal_flag'` 再求和。 -> **v1.x 读数不可复现的订正说明**:原记载「~314 处(270 处 .gd + 22 处 .tres + 22 独立 flag 词)/29 个 .gd 文件」来自审计报告,其计数口径(疑为 `flag_` 前缀且不含注释内英文词)在现行代码上两种口径都对不上——单文件抽样:`minesweeper_rules.gd` 原记 18、`flag_` 前缀口径 18、`flag` 全口径 59;`smoke_all.gd` 原记 105、两种口径分别 136/157。**低估面约为实测的 1.9 倍,文件数少记 24 个**。§6 估时 ≈3.75d 是按旧读数定的,是否上调归编排段/用户(本卡不改估时)。完成判据不受影响——V1 本来就是「grep 零命中」,与计数无关。 - -**核心逻辑文件(v1.4 实测:净命中=`flag` 处数 − `size_flags_*` − `_fatal_flag`;降序,2026-10-18)**: - -| 文件 | 净命中 | 关键标识符 | -|---|---|---| -| smoke/smoke_all.gd | 156 | flag_place, flag_hit, flag_miss, flag_placed, _flag_consumed + 注释断言文本 | -| core/minesweeper_rules.gd | 59 | flag_place, has_flag, flag_range_free, _flag_miss_seen, was_flagged, dug_under_flag 载荷键(:300/:306/:313/:348) | -| smoke/ui_input_probe.gd | 40 | flag_place, flag_cell | -| core/settlement/grant_segment.gd | 38 | flag_hit, flag_miss, _flag_consumed, flag_settle, dug_under_flag(:30/:93) | -| core/battle_orchestrator.gd | 33 | flag_hit, flag_hit_premium, _flag_consumed | -| smoke/level_autoplay.gd | 30 | flag_placed, flag_hit, flag_miss | -| presentation/views/board_view.gd | 23 | tex_flag, has_flag, flag_cell | -| smoke/ui_click_probe.gd | 21 | **_flags_placed**(:22 声明+:263/:279/:287/:309/:330 等清空点)——v1.3 的 T5.4 只记了「注释插旗 3 处」,漏了 18 处标识符 | -| data/tables/feats.tres | 15 | "flag_hit"(on 触发), "echo_flags", "smith_flags", "flag_burst"(feat_id), "dug_under_flag"(fact) | -| core/effect_engine.gd | 15 | `EVENTS` 含 flag_hit(:13)、flag_missed(:15);`MINE_EVENTS` 含 flag_hit、flag_settle(:20);**`FACTS` 含 flags_count(:51)与 dug_under_flag(:52)**——v1.3 的 T3.1 漏了 FACTS 两键;天赋树合成行 `{"on": "flag_missed"}`(:149、:152) | -| smoke/adventure_monte_carlo.gd | 14 | flag_placed, flag_hit, flag_miss(MC 输出键源) | -| smoke/auto_player.gd | 13 | flag_place 调用+注释「雷格」 | -| presentation/views/battle_end_overlay.gd | 11 | flag_hit, flag_miss 统计显示 | - -**净命中 >0 的文件共 42 个**(其余 15 个含 `flag` 的文件只有 `size_flags_*`/`_fatal_flag` 假阳性)。上表列 13 个,余 29 个净 1–8 处,其中 **v1.3 任务卡完全未列的 5 个**(v1.4 已补进 T5.20–T5.24):`smoke/screen_flow_probe.gd` 8(`_screen_flags`/`_flags_text`/`_expect_adventure_flag`)、`tests/unit/core/effect_words_t1_test.gd` 2(**断言 `FACTS.has("dug_under_flag")`——不改必红**)、`smoke/ui_probe.gd` 2、`smoke/type_glow_shot_probe.gd` 2(`kind == "flag"`/`op = "flag_place"`)、`smoke/fx_probe.gd` 2(`flag_dots` 键)。 - -**数据表字段(.tres 键名,改动必须与 schema .gd 同步)**: - -| 文件 | 字段 | 改后 | -|---|---|---| -| action_economy.tres:9 | `flag_place_ap_cost = 1` | `seal_place_ap_cost = 1` | -| settlement.tres:9 | `flag_hit_premium = 125` | `seal_hit_premium = 125` | -| settlement.tres:13 | `"flag_hit": "标中旗"` | `"seal_hit": "封印命中"` | -| settlement.tres:18 | `"flag_miss": "标旗未中"` | `"seal_miss": "封印未中"` | -| feats.tres:257,305,320,328,352,806,844 | `"on": "flag_hit"` | `"on": "seal_hit"` | -| feats.tres:260,269,285,292 | `"echo_flags"` | `"echo_seals"` | -| feats.tres:323,332 | `"smith_flags"` | `"smith_seals"` | -| feats.tres:838 | `"feat_id": "flag_burst"` | `"feat_id": "seal_burst"` | -| feats.tres:615 | `"fact": "dug_under_flag"` | `"fact": "dug_under_seal"` | -| treasure_items.tres:223 | `"flag_range_free"` | `"seal_range_free"` | - -**Schema 校验文件(.gd 中读 .tres 键名的代码)**: - -| 文件 | 涉及 | -|---|---| -| data/schemas/action_economy_table.gd | 读 flag_place_ap_cost(4 处) | -| data/schemas/settlement_table.gd | 读 flag_hit_premium(3 处) | -| data/schemas/treasure_item_table.gd | 读 flag_range_free(3 处) | -| core/action_economy.gd | "flag_place" 事件名(2 处) | -| core/config_db_cross_validator.gd | required_sources 含 "flag_hit", "flag_miss"(2 处) | - -**Godot 信号声明(API 契约,连接方必须同名)**: - -| 文件 | 声明/连接 | 改后 | -|---|---|---| -| core/minesweeper_rules.gd:9 | `signal flag_judged(evt: Dictionary)` | `signal seal_judged(evt: Dictionary)` | -| core/battle_orchestrator.gd:287 | `minesweeper.flag_judged.connect(_on_flag_judged)` | `minesweeper.seal_judged.connect(_on_seal_judged)` | - -**已知假阳性(显式排除,不改)**: - -| 文件 | 标识符 | 原因 | -|---|---|---| -| **`game/` 内 19 个 .gd 文件全体**(v1.4 订正:v1.3 只写了 ui_assembler.gd 一个,漏 18 个) | `size_flags_*`(含 `size_flags_vertical`/`size_flags_horizontal`/`size_flags_stretch_ratio`,共 70 处) | Godot 引擎 Control 内置属性与布局写法,禁改 | -| core/config_db.gd | `_fatal_flag`(4 处) | 无关变量(致命错误标记),禁改 | -| presentation/views/ui_assembler.gd:203 | 注释里的「min/flags」字样 1 处 | **不是豁免项,须改写注释**(v1.4 订正)——V1 判据是「grep `flag` 零命中减两类假阳性」,这处注释既非 `size_flags_*` 也非 `_fatal_flag`,不改写则 V1 永远红一项。改法:把「0=不设 min/flags」写成「0=不设最小宽度」 | - -**存档影响面(Alpha 阶段可接受作废,不做迁移)**: - -| 持久化路径 | 涉及键 | 影响 | -|---|---|---| -| save.json → breakpoint.adventure_counters | `"echo_flags"`, `"smith_flags"` | 旧档计数器失效,Alpha 阶段可接受(2026-10-18 用户裁定) | - -### N2 · 中文禁用词分布(v1.4 实测,`game/` 内 .gd+.tres,2026-10-18) - -| 禁用词 | 实测处数/行数/文件数 | 主要落点(实测 top 3 文件) | -|---|---|---| -| 金币 | 39 / 36 / 16 | smoke_all 10、shop_overlay_view 5、camp_shop_presenter 3(+battle_narrator 2、curio_pick_overlay 2、legend_overlay 1 等 UI 字符串) | -| 插旗 | 62 / 60 / 23 | smoke_all 14、grant_segment 6、**tests/unit/core/minesweeper_rules_test.gd 4**(v1.3 误记为 minesweeper_rules.gd 4) | -| 雷格 | 75 / 70 / 19 | smoke_all 31、battle_orchestrator 11、minesweeper_rules 5(+grant_segment、board_generator、测试断言文本) | -| 惩罚格 | 1 / 1 / 1 | treasure_items.gd 注释(v1.3 记 ~2 处,实为 1) | -| 旗(含复合词) | **376 / 285 / 50** | 内已含 插旗 62、标中旗 21、标旗 20;其余为注释里的「旗格/旗判定/旗溢价/旧板旗/无旗/拔旗/旗经济」等散句,v1.3 记 ~15 处严重低估——但落点几乎全是注释与断言描述文本,按 §9 代拍板白名单第 1、3 条语义等价改写即可,不需逐条请示 | - -### N3 · .tres 中文禁用词 - -| 文件 | 命中 | -|---|---| -| reward.tres:188 | `"display_name": "金币袋"` | -| reward.tres 注释 | 金币袋、雷格(~5 处) | -| feats.tres:10-11 | 注释含「插旗=封印」「禁『雷/插旗』字面」 | -| treasure_items.tres:212 | `"desc": "插旗不限相邻(可对任何未开格插旗)"` | -| settlement.tres:13,18 | `"标中旗"` / `"标旗未中"` | -| action_economy.tres:18 | 注释含「雷格」 | -| status_effects.tres:96 | 注释含「雷格」 | - -### N4 · game/README.md - -雷格 8 处、插旗 1 处,均为架构说明注释。 - -### 关联面(本卡不动) - -- design/ 目录文档面(另批委派处理) -- tools/*.py 中的「雷格」(analyze_playtest.py 1 处、render_sample_sheet*.py 6 处)——归文档批或工具批 -- sim-data/analyze.py(1 处雷格)——同上 -- 术语表自身修正——归文档批 - -## 3. 设计契约(红线,违反=L3 停机呈报) - -- 🔴 **游戏行为零变化**:本批是纯重命名/文本替换,禁止改动任何游戏逻辑、数值、权重、条件判断。改前改后同种子冒烟读数必须逐位一致。 -- 🔴 **.tres 键名与 schema .gd 必须同批同步**:改 settlement.tres 的 `flag_hit_premium` 必须同批改 settlement_table.gd 里读它的代码,否则数据加载失败。 -- 🔴 **事件名字符串全链一致**:`"flag_hit"` 作为事件名贯穿 effect_engine.gd EVENTS 常量 → grant_segment.gd 发射 → feats.tres `"on"` 触发 → config_db_cross_validator.gd 校验 → battle_log_view.gd 呈现。改一处必须全链同步。 -- 🔴 **Godot 信号声明与连接同名**:`signal flag_judged`(minesweeper_rules.gd:9)→ `seal_judged`;连接方 `battle_orchestrator.gd:287` 的 `.connect(_on_flag_judged)` → `.connect(_on_seal_judged)`;回调函数名同步。 -- 🔴 **冒烟断言文本同步**:smoke_all.gd 中 check() 的描述字符串含「雷格」「插旗」「金币」的,随批替换;断言逻辑(数值、条件)零改动。 -- 🔴 **显式排除清单(假阳性)**:`size_flags_vertical` / `size_flags_horizontal` / `size_flags_stretch_ratio`(Godot 引擎 Control 属性,ui_assembler.gd)与 `_fatal_flag`(config_db.gd 无关变量)**不在重命名范围**,盲替换命中即 L3。 -- 🔴 **本批不保证旧存档兼容**:`echo_flags` / `smith_flags` 等 counter_id 持久化在 save.json 的 `breakpoint.adventure_counters` 中,重命名后旧档该键失效。Alpha 阶段可接受存档作废,不做迁移逻辑(2026-10-18 用户裁定)。 -- 🔴 **不改 design/ 目录**:实现批禁写 design/(process-conventions §3 第 13 条)。 -- 🔴 **不改 tools/*.py**:工具脚本归文档批。 -- 🔴 **FACTS 两键全链同步(v1.4 补,v1.3 完全漏列)**:`flags_count`→`seals_count` 三处落点(`core/effect_engine.gd:51` 词表、`core/battle_orchestrator.gd:180` 载荷、`core/settlement/grant_segment.gd:179` 发射);`dug_under_flag`→`dug_under_seal` 十一处落点(`effect_engine.gd:47/:52`、`minesweeper_rules.gd:300/:306/:313/:348`、`grant_segment.gd:30/:88/:93`、`data/tables/feats.tres:615`、`smoke/smoke_all.gd:1559/:1560`、`tests/unit/core/effect_words_t1_test.gd:18/:21`)。改词表不改消费者=运行期取不到事实值;改消费者不改词表=加载期四词表校验致命。两名现行代码零占用(实测 `seals_count`/`dug_under_seal` 各 0 命中),无重名风险。 -- 🔴 **非游戏语境的 flag 不动**:如 `git flag`、编译标志等(实查 game/ 内无此情况,但作为纪律登记)。 -- 🔴 **与卡② 的命名接续(2026-10-18 用户补裁,v1.3 新增)**:本卡合回后,卡②(凭证件裁削批)新写的标识符一律 `seal_` 族——其效果类型名 `forgive_flag_miss` 已由同日补裁换代为 **`forgive_seal_miss`**,事件订阅写 `on: "seal_missed"`。故本卡的 V1「`flag` 零命中」在迭代 31 出口仍成立,不需要为卡② 打排除补丁。本卡执行时 `flag_missed` 必须一并改名为 `seal_missed`(原 v1.2 映射表漏列,v1.3 补入 T3.1)。 - -## 4. 范围边界 - -**做**: - -- game/ 目录内全部 .gd、.tres、.md 文件的 flag→seal 重命名与中文禁用词替换 -- 替换后全量冒烟+单元测试验证 - -**不做(去向)**: - -| 不做的 | 去向 | -|---|---| -| design/ 全部文档 | 文档批(用户委派另会话) | -| tools/*.py | 文档批或工具批 | -| sim-data/ | 同上 | -| 术语表自身修正 | 文档批 | -| 游戏逻辑/数值改动 | 禁止(本批纯重命名) | -| doc_term_audit.py 词表扩充与扫描域扩展 | 文档批(T5) | - -## 5. 关联文档同步面 - -> **口径(v1.3,2026-10-17 起生效)**:本批禁写 `design/` 整目录与根规则文件,唯一可写目录=`reports/`。下表凡标「反哺点」者=把「哪个文件哪一节、改成什么、依据是什么」写进 `reports/iter31-反哺点-<日期>.md`,由用户裁决后归文档批落文;本批一律不落笔 `design/`。v1.2 及以前的「机械面随批」措辞作废。 - -| 文档 | 关联点 | 同步义务 | -|---|---|---| -| [06-待办清单](../design/gdd/06-待办清单.md) | 「代码术语刷新批」条目状态推进为「已完成(迭代 31 卡①,合并 ``,2026-10-XX)」 | **反哺点**(`design/` 内,本批禁写):推进句写进 `reports/iter31-反哺点清单`,文档批落笔后本条清掉 | -| [术语表](../design/gdd/术语表.md) | flag→seal 重命名后,术语表「旗/控制」条目需同步改为「封印/控制」 | **反哺点**:文档批处理,本卡不改 design/ | -| [entities.yaml](../design/registry/entities.yaml) | 第 268 行「机制键与规则(flag_place/flag_rules/标中旗三向效果)全不变,纯呈现层命名」+source_label_map 键集标注「结构冻结」——代码批执行后此条款失效,需解冻并换代为 seal_* | **反哺点**:文档批需显式废止「结构冻结」条款、将 flag_* 契约键全部换代为 seal_*。窗口期(代码已改、registry 未改)可接受——registry 非运行时依赖(2026-10-18 grilling Q4 裁定) | -| game/README.md | 架构说明中雷格/插旗 | **本批直改**(文件在 `game/` 内,不属 `design/` 禁写面)——随批替换 | -| game/tests/evidence/parity/anchor.json | MC 输出基线含 ~600 处 flag_* 键(flag_hit/flag_hit_gain/flag_miss/flag_miss_penalty/flag_placed/flag_burst) | **本批直改**(在 `game/` 内):手动替换键名(行为零变化故不重跑 MC),替换后跑 parity 闸确认绿 | -| [07-体验验证清单](../design/gdd/07-体验验证清单.md) | UI 文本换代后目检项 | **反哺点**:登记「商店/图例/HUD 文本是否显示 GP/封印而非金币/插旗」目检项,文档批落 | - -## 6. 任务卡 - -### T0 · 基线记录(≈10min) - -1. 跑全量冒烟(smoke_all.gd),记录绿数基线。 -2. 跑单元测试(tests/run_all.gd),记录套数与绿数。 -3. 记录当前 game/ 内 `flag` 总命中数(grep 计数,作为改后零残留的对照)。 - -### T1 · .tres 数据文件重命名(≈0.5d) - -先改数据层(被 .gd 读取的源头),再改 .gd 消费侧,避免中间态加载失败。 - -1. action_economy.tres:`flag_place_ap_cost` → `seal_place_ap_cost`;注释中「雷格」→「危险格」 -2. settlement.tres:`flag_hit_premium` → `seal_hit_premium`;`"flag_hit": "标中旗"` → `"seal_hit": "封印命中"`;`"flag_miss": "标旗未中"` → `"seal_miss": "封印未中"`;注释中「雷格」→「危险格」 -3. feats.tres:全部 `"on": "flag_hit"` → `"on": "seal_hit"`;`echo_flags` → `echo_seals`;`smith_flags` → `smith_seals`;`flag_burst` → `seal_burst`;`dug_under_flag` → `dug_under_seal`;注释中「插旗」→「封印」 -4. treasure_items.tres:`flag_range_free` → `seal_range_free`;desc「插旗不限相邻(可对任何未开格插旗)」→「封印不限相邻(可对任何未开格封印)」 -5. reward.tres:`"display_name": "金币袋"` → `"display_name": "GP 袋"`;注释中「金币袋」「雷格」替换 -6. status_effects.tres:注释中「雷格」→「危险格」 - -### T2 · Schema .gd 同步(≈0.25d) - -与 T1 同批完成(.tres 键名改了,读它的 schema 必须同步): - -1. action_economy_table.gd:flag_place_ap_cost → seal_place_ap_cost(4 处) -2. settlement_table.gd:flag_hit_premium → seal_hit_premium(3 处) -3. treasure_item_table.gd:flag_range_free → seal_range_free(3 处) -4. reward_table.gd:注释中「雷格」→「危险格」 - -### T3 · 核心逻辑 .gd 重命名(≈1d) - -按依赖序改(底层→上层): - -1. core/effect_engine.gd:EVENTS/MINE_EVENTS 常量 "flag_hit"→"seal_hit", "flag_settle"→"seal_settle", **"flag_missed"→"seal_missed"**;**FACTS 两键:"flags_count"→"seals_count"(:51)、"dug_under_flag"→"dug_under_seal"(:52)**(v1.4 补——v1.3 的 T3.1 漏了 FACTS,改了 .tres 的 fact 值而词表不放行=加载期校验致命);天赋树合成行 :149/:152 的 `{"on": "flag_missed"}` 同步改名;头注 :9 文本随批(净 15 处,以 V1 grep 零命中为准) -2. core/minesweeper_rules.gd:flag_place→seal_place, has_flag→has_seal, flag_range_free→seal_range_free, _flag_miss_seen→_seal_miss_seen(18 处)+注释中「插旗」「雷格」替换 -3. core/action_economy.gd:"flag_place"→"seal_place"(2 处) -4. core/battle_orchestrator.gd:flag_hit→seal_hit, flag_hit_premium→seal_hit_premium, _flag_consumed→_seal_consumed(17 处)+注释替换 -5. core/settlement/grant_segment.gd:flag_hit→seal_hit, flag_miss→seal_miss, _flag_consumed→_seal_consumed(23 处)+注释中「插旗」「雷格」替换 -6. core/config_db_cross_validator.gd:required_sources 中 "flag_hit"→"seal_hit", "flag_miss"→"seal_miss"(2 处)+注释「雷格」 -7. core/reward_economy.gd:注释「雷格」→「危险格」 -8. core/board_generator.gd:注释「雷格」→「危险格」 -9. core/treasure_items.gd:注释「插旗」「惩罚格」替换 - -### T4 · 呈现层 .gd 重命名+UI 字符串(≈0.5d) - -1. presentation/views/board_view.gd:tex_flag→tex_seal, has_flag→has_seal, flag_cell→seal_cell(7 处)+注释 -2. presentation/views/board_cell_unit.gd:tex_flag→tex_seal(2 处)+注释「插旗」「雷格」 -3. presentation/views/shop_overlay_view.gd:UI 字符串「金币」→「GP」(5 处) -4. presentation/camp_shop_presenter.gd:「金币不足」→「GP 不足」(3 处) -5. presentation/curio_interact_controller.gd:「金币不足」→「GP 不足」(1 处) -6. presentation/battle_narrator.gd:「金币」→「GP」(2 处) -7. presentation/views/curio_pick_overlay.gd:「金币」→「GP」(2 处) -8. presentation/views/legend_overlay.gd:「金=金币」→「金=GP」;「右键插旗」→「右键封印」;「旗」→「封印印记」(3 处) -9. presentation/hud_presenter.gd:「不能插旗:此格已有旗」→「不能封印:此格已有封印印记」(1 处) -10. presentation/main.gd:「插旗后轮末自动判定标中」→「封印后轮末自动判定」(2 处)+注释 -11. presentation/views/battle_log_view.gd:"flag_miss"→"seal_miss"(1 处)+注释「金币」 -12. presentation/views/battle_end_overlay.gd:flag_hit/flag_miss 统计键(9 处) -13. presentation/views/ui_kit.gd:注释「金币」「插旗」「雷格」+TEX_ICON_COINBAG 注释 -14. presentation/views/level_map_screen.gd:注释「金币」 -15. presentation/views/board_fx_view.gd:flag 相关(1 处) -16. presentation/views/standee_body.gd:flag 相关(1 处) -17. presentation/row_pacer.gd:"flag_hit"→"seal_hit"(2 处) -18. presentation/views/status_slot_row.gd:flag 相关(1 处) - -### T5 · 冒烟与测试 .gd 重命名(≈1d) - -1. smoke/smoke_all.gd:105 处 flag_ 替换+注释/断言文本中「金币」「插旗」「雷格」替换(~50 处) -2. smoke/level_autoplay.gd:16 处 flag_ +注释「插旗」 -3. smoke/ui_input_probe.gd:23 处 flag_ +注释「插旗」 -4. smoke/ui_click_probe.gd:净 21 处——`_flags_placed` 声明(:22)+各清空点(:263/:279/:287/:309/:330 等)改名 `_seals_placed` +注释「插旗」3 处(v1.4 订正:v1.3 只记了注释,漏 18 处标识符) -5. smoke/adventure_monte_carlo.gd:5 处 flag_ +注释 -6. smoke/auto_player.gd:注释「雷格」(4 处) -7. smoke/fx_shot_probe.gd:注释「插旗」(1 处) -8. smoke/board_shot_probe.gd:"flag_place"→"seal_place"(1 处) -9. smoke/ui_contrast_probe.gd:注释「金币」(1 处) -10. tests/unit/core/minesweeper_rules_test.gd:flag 相关(5 处)+「插旗」 -11. tests/unit/core/board_generator_test.gd:「雷格」(1 处) -12. tests/unit/core/treasure_effects_test.gd:flag 相关(3 处)+「插旗」 -13. tests/unit/core/feat_vouchers_test.gd:「金币」(1 处) -14. tests/unit/presentation/hud_presenter_test.gd:「插旗」(1 处) -15. tests/unit/presentation/reward_overlay_test.gd:「金币」(2 处) -16. tests/unit/core/tree_rules_v11_test.gd:flag 相关(2 处) -17. tests/unit/core/treasure_items_test.gd:flag 相关(1 处) -18. tests/run_all.gd:注释「插旗」(1 处) -19. tests/smoke/critical-paths.md:「雷格」「插旗」(2 处) -20. **smoke/screen_flow_probe.gd:净 8 处(v1.4 补列,v1.3 全漏)**——`_screen_flags()`(:50)、`_flags_text()`(:59)、`_expect_adventure_flag()`(:68)三函数改名 + 调用点(:75/:83/:91 等)。注意:本件是 L3 屏壳探针,受 `user://save.json` 断点污染的在册已知项,跑红先按该条排查再判归因 -21. **tests/unit/core/effect_words_t1_test.gd:净 2 处(v1.4 补列)**——断言 `FACTS.has("dug_under_flag")`(:18)与描述文本(:21)须随 FACTS 词表改 `dug_under_seal`,**不改即红**(与 §3 FACTS 全链契约同批) -22. **smoke/ui_probe.gd:净 2 处(v1.4 补列)**——数据行里的 flag 族键/字符串(:179 附近),逐处改名 -23. **smoke/type_glow_shot_probe.gd:净 2 处(v1.4 补列)**——`kind == "flag"`(:60)与 `op = "flag_place"`(:61) -24. **smoke/fx_probe.gd:净 2 处(v1.4 补列)**——`flag_dots` 键(:64/:65)须与发射端同名改 - -**余下 29 个净 1–8 处的文件不逐列**(净处数总和 543,V1 的 grep 零命中判据即兜网):施工期每轮以「净命中文件数递减、终态 42→0」为进度读数,发现卡片未列的落点属正常,按 §3 契约同步即可,不属卡片缺陷。 - -### T6 · game/README.md+anchor.json+全量验证(≈0.5d) - -1. game/README.md:雷格(8 处)→危险格、插旗(1 处)→封印 -2. game/tests/evidence/parity/anchor.json:手动替换全部 flag_* 键名为 seal_*(~600 处:flag_hit→seal_hit, flag_hit_gain→seal_hit_gain, flag_miss→seal_miss, flag_miss_penalty→seal_miss_penalty, flag_placed→seal_placed, flag_burst→seal_burst) -3. 全量冒烟+单元测试,绿数与 T0 基线一致 -4. parity 闸跑通(anchor.json 键名替换后与 MC 新输出一致) -5. 全局搜索验证:game/ 内 `flag`(排除 size_flags_* 和 _fatal_flag)零命中;「金币」「插旗」「雷格」「惩罚格」零命中 -6. **产出物落位卡**(req-card §7:末卡必含):`reports/` 三份写齐——`iter31-实现报告-<日期>.md`(含 V1–V7 读数+改前改后同种子读数对照+实机目检总清单)、`iter31-代拍板-<日期>.md`、`iter31-反哺点-<日期>.md`(§5 每条反哺点都要有落点:06 推进句/术语表/entities.yaml/07 目检项)。**禁改 `design/` 与 `roadmap.md`** - -**估时合计 ≈3.75d**(v1.4 注:实测面约为 v1.3 旧读数的 1.9 倍(净 543 处/42 文件 vs 原记 ~314 处/29 文件),但落点高度集中在 `smoke_all.gd`(净 156 处=全集 29%),改动是机械替换+grep 兜网。**2026-10-18 用户裁:不上调**,估时保持 ≈3.75d;roadmap 迭代 31 行预计周期同步维持「≈1.5 周」不变)。 - -## 7. 验证闸(逐需求点验收清单) - -**能力验证(自动化,随批)**: - -- **V1(N1)**:改后全局 grep `flag` game/ 目录,排除 `size_flags_*` 和 `_fatal_flag` 后零命中。 -- **V2(N1)**:全量冒烟绿数 == T0 基线(行为零变化证词)。 -- **V3(N1)**:单元测试绿数 == T0 基线。 -- **V4(N2/N3)**:改后全局 grep「金币」「插旗」「雷格」「惩罚格」game/ 目录零命中。 -- **V5(N2)**:settlement.tres 的 source_class 显示名不含「旗」字(「封印命中」「封印未中」)。 -- **V6(回归)**:同种子冒烟读数逐位一致(纯重命名不改行为的最强证词)。 -- **V7(parity)**:anchor.json 键名替换后 parity 闸绿(MC 输出与基线逐位一致)。 - -**正常流程体验(用户目检,登记 07 不阻塞)**: - -1. 商店界面显示「GP」而非「金币」。 -2. 图例/HUD 显示「封印」而非「插旗」「旗」。 -3. 结算明细来源显示「封印命中」而非「标中旗」。 - -## 8. 异常分级 - -- **L1(自救)**:单个文件漏改导致 grep 验证未过——补改即修,不改批结构。 -- **L2(记录继续)**:冒烟绿数与基线偏差 ≤2(断言文本替换引起的描述性变化,非逻辑变化)——记录偏差原因,确认非逻辑回归后继续。 -- **L3(停机呈报)**:冒烟绿数下降 >2 或出现逻辑断言红(说明重命名触及了行为);.tres 加载失败(schema 不同步);同种子读数不一致(行为变化)。 - -## 9. 代拍板白名单(超清单必呈报) - -1. 注释替换时的措辞微调(如「挖雷格」→「挖危险格」vs「挖掘危险格」)——语义等价即可,不必逐条请示。 -2. seal_* 的具体拼写形态(如 `_seal_consumed` vs `_consumed_seals`)——与 flag_* 原形态保持同构即可。 -3. 测试断言描述文本的替换措辞——语义等价即可。 -4. settlement.tres 显示名「封印命中」「封印未中」的具体措辞——若用户有异议呈报。 - -## 10. 待裁点 - -**零待裁点,开工门=U0。** Q1–Q3 于 2026-10-18 用户令「按推荐来」全裁;Q4–Q8 于同日 grilling 复核后用户裁定落定: - -| # | 裁定 | 落定结论 | -|---|---|---| -| Q1 | reward.tres display_name | **GP 袋**(金币袋→GP 袋) | -| Q2 | settlement.tres 显示名 | **封印命中 / 封印未中**(标中旗→封印命中、标旗未中→封印未中) | -| Q3 | feats.tres feat_id | **seal_burst**(flag_burst→seal_burst) | -| Q4 | 存档兼容 | **不做迁移,Alpha 阶段旧存档可作废**(echo_flags/smith_flags 计数器失效可接受) | -| Q5 | anchor.json 处理 | **手动替换键名**(行为零变化不重跑 MC),替换后跑 parity 闸确认绿 | -| Q6 | 假阳性排除 | **显式排除清单入红线**:size_flags_*(Godot 引擎属性)、_fatal_flag(config_db 无关变量) | -| Q7 | registry 契约窗口期 | **可接受**(registry 非运行时依赖;文档批紧随其后;entities.yaml「结构冻结」条款标注为反哺点,文档批需显式废止并换代) | -| Q8 | 信号声明补全 | **signal flag_judged → seal_judged 显式入映射表**(Godot 信号=API 契约,连接方必须同名) | - ---- - -**卡片成立前置**:~~grilling 复核门~~(2026-10-18 已过,Q4–Q8 全裁)+~~用户卡审~~(2026-10-18 已过,用户确认编入迭代 31)。 diff --git a/reports/需求卡片-凭证件裁削批-2026-10-18.md b/reports/需求卡片-凭证件裁削批-2026-10-18.md deleted file mode 100644 index eaec4a59..00000000 --- a/reports/需求卡片-凭证件裁削批-2026-10-18.md +++ /dev/null @@ -1,216 +0,0 @@ -# 需求卡片·凭证件裁削批(代码侧迁移) - -- **批次名**:凭证件裁削批(代码侧) -- **日期**:2026-10-18 -- **批次性质**:工程债/错置修正(凭 06 在册条目直接写卡;设计已于同日文档批在奇物.md v3.18 定稿) -- **设计事实源**(req-card §2 三选一之①GDD 文档节+版本号,2026-10-18 立规;v1.1 补声明):`design/gdd/systems/冒险循环/奇物.md` **v3.18**(删件/迁出/配额净删三段定稿)。**前置门见 §10**。 -- **标识符形态通则(v1.1,2026-10-18 用户补裁)**:本卡成文于卡① 之前。凡卡① 改名范围内的标识符(`flag_hit`/`flag_miss`/`flag_missed`/`flag_settle`/`flag_judged`),本卡 §2 现状事实的旧名与行号**按卡① 合回后的 `seal_` 形态**复核执行,不逐处更新旧名;本卡新写的标识符一律 `seal_` 族——效果类型名取 **`forgive_seal_miss`**(取代 D1 原裁 `forgive_flag_miss`),feats.tres 触发行写 `on: "seal_missed"`。 -- **版本**:**v1.1**(2026-10-18 卡片冲突修订批:补设计事实源与标识符形态通则;D1 换代为 `forgive_seal_miss`;契约 3/8 订正;§5/§6 文档同步义务改为 `reports/` 反哺点清单;§10 补前置门。原 v1.0=2026-10-18 立卡) -- **迭代归属**:迭代 31 第二张卡(与卡①「代码术语刷新批」串行) -- **上游依据**:用户 2026-10-18 逐裁四项——①同调电池**删除**;②完美保险**改归专长**、语义档=**甲(每战首次封印落空豁免)**;③desc 用 A「本场首次封印落空,不计入完美封印判定」;④寿命域**本批不动**、完美保险按现役 `domain=battle` 落地;配额处置=**净删**(rare 9→7/总量 104→102) - ---- - -## 1. 目标与完成定义 - -**目标**:把用户 10-18 两项裁断落到代码与数据表——同调电池自奇物体系整体删除、完美保险自资源类迁入专长表并按订阅式重写——同时完成 `TIER_QUOTAS` 结构锚的重裁落地。 - -**完成定义**(全部满足才算完): - -1. `CURIO_KINDS` 不再含 `attune_battery`/`perfect_insurance`,两件在三选一池不可再出现; -2. 同调电池的 runner 侧全部入口(待分配账、玩家点选函数、getter、断点键)清零,无孤儿引用; -3. `feats.tres` 增完美保险专长行,四词表校验通过,效果引擎装载并可派发; -4. 完美排雷判定改为「误标总数 − 豁免数」两账相减式,`_perfect_hit_false` 保持纯净、不被任何效果改写; -5. `TIER_QUOTAS` rare 9→7、总量 104→102,`validate()` 硬断言通过; -6. 代码域闸全绿(冒烟+单元测试+场景探针+改前改后读数对拍)+`reports/` 三份产出物写齐(实现报告/代拍板追认单/反哺点清单)。**文档面(奇物.md 指针销号、entities.yaml 104→102、07 观测项、roadmap 行)不在本条完成定义内**——实现批禁写 `design/` 与根规则文件,一律列进反哺点清单归文档批落笔(v1.1 订正,原句「机械面文档同步完毕」属 2026-10-17 改口径前的旧措辞)。 - ---- - -## 2. 现状事实(代码级,开工自行复核) - -### 2.1 同调电池(待删) - -| 位置 | 事实 | -|---|---| -| `game/data/schemas/adventure_table.gd:21-22` | `CURIO_KINDS` 含 `"attune_battery"` | -| `adventure_table.gd:59` | `curio_quota_attune_battery_rare = 1`(rare 档投放) | -| `adventure_table.gd:76` | `curio_value_attune_battery_rare = 1`(充能 +N) | -| `adventure_table.gd:91` | `curio_cap_attune_battery = 99` | -| `adventure_table.gd:138` | 配额分发表分支 `["attune_battery", TIER_RARE]` | -| `adventure_table.gd:159` | 件值分发表分支 | -| `adventure_table.gd:176` | cap 分发表分支 | -| `game/core/adventure_runner.gd:55` | `_battery_pending`(冒险级待分配充能) | -| `adventure_runner.gd:213` | 断点回填 `battery_pending` 键 | -| `adventure_runner.gd:261` | 冒险开局重置 | -| `adventure_runner.gd:415-417` | `_apply_curio_pick` 路由分支 | -| `adventure_runner.gd:598-610` | `choose_battery_target(item_id)`——玩家点选分配 | -| `adventure_runner.gd:615-616` | `battery_pending()` getter | -| `adventure_runner.gd:1076` | 断点存档键 `"battery_pending"` | -| `game/tests/unit/core/feat_vouchers_test.gd:56-64` | V9-5 断言组(兑付受理/待分配 1/禁自动替选反例/跨层写账) | - -**关键事实**:`choose_battery_target` 的调用方只有定义自身、getter、单元测试与断点键——**呈现层零接线**(全库检索 `battery`/电池在 presentation 层零命中)。玩家拿到电池后 `_battery_pending` 挂着花不出去,且随断点一直挂下去。它不是「零途径所以撤」,而是「有 API 有账本有测试、唯独没有玩家入口」。 - -### 2.2 完美保险(待迁专长) - -| 位置 | 事实 | -|---|---| -| `adventure_table.gd:21-22` | `CURIO_KINDS` 含 `"perfect_insurance"` | -| `adventure_table.gd:61` | `curio_quota_perfect_insurance_rare = 1` | -| `adventure_table.gd:78` | `curio_value_perfect_insurance_rare = 1` | -| `adventure_table.gd:93` | `curio_cap_perfect_insurance = 99` | -| `adventure_table.gd:140`/`:161`/`:178` | 配额/件值/cap 三处分发表分支 | -| `adventure_runner.gd:57` | `_pending_insurance`(节点级,下一战标错豁免 N 次) | -| `adventure_runner.gd:263` | 冒险开局重置 | -| `adventure_runner.gd:423-425` | `_apply_curio_pick` 路由分支 | -| `adventure_runner.gd:920-923` | 战首 `set_voucher_grants(...)` 注入后清零 | -| `game/core/battle_orchestrator.gd:81` | `_fx_insurance`(本战标错豁免余量) | -| `battle_orchestrator.gd:422` | `_fx_insurance = enc.get("voucher_insurance", 0)` | -| `battle_orchestrator.gd:266-267` | `_perfect_hit_true`/`_perfect_hit_false`(板级计数,install 重置) | -| `battle_orchestrator.gd:471-472` | install 重置点 | -| `game/core/settlement/grant_segment.gd:295-308` | 标错时 `_perfect_hit_false += 1`;`_fx_insurance > 0` 则 `-=1` 且 `_perfect_hit_false -= 1`(回退)+归因行 | -| `grant_segment.gd:314` | `flag_missed` 事件发射(**晚于计分**) | -| `feat_vouchers_test.gd:52-53` | V9-4 断言(兑付受理/豁免待注入 1) | - -**判定式现状**:`_perfect_hit_false == 0 && _perfect_hit_true >= 1` → 完美成立(权威定义 `entities.yaml:254`:板级零误标 ∧ ≥1 标中 → 清图奖励当量 ×P_perfect,默认 ×2)。 - -### 2.3 配额结构锚 - -`adventure_table.gd:34`:`TIER_QUOTAS := {"common": 70, "excellent": 25, "rare": 9, "legendary": 0}`(总量 104)。现行分配:rare=ap 3+rap 2+attune_battery 1+time_sand 2+perfect_insurance 1=9。`:4`/`:30-33` 明载「改投放总量=重裁非调参,`validate()` 硬断言」。 - -### 2.4 效果引擎词表 - -`game/core/effect_engine.gd`:`EVENTS`(:13-16,已含 `flag_missed`,迭代 21 T3 扩签)/`EFFECT_KINDS`(:25-41,**现 31 项**,v1.1 订正——原记 30 项,无豁免型;本卡 T4 加 `forgive_seal_miss` 后为 32)/`FACTS`(:50-54,含 `counter`)/`OPS`(:61-62,含 `lt`)/`DO_KEYS`(:72-75,含 `domain`=battle/adventure)。四词表出域=加载期校验致命。 - ---- - -## 3. 设计契约(🔴 触碰=L3 停机呈报) - -1. 🔴 **`attune_charges` 账本与 `_seed_attune_charges` 禁删**(`adventure_runner.gd:29/:109/:201/:243/:559-564`)——迭代 11 秘宝基础设施(主动件充能每冒险重置)。本批只删奇物侧写它的入口,不碰账本本体。 -2. 🔴 **`_perfect_hit_false` 保持纯净**:任何效果不得改写该值。豁免必须走「自有累加计数 + 判定时相减」,即新增 `_perfect_forgiven` 单向累加,判定取 `effective_miss = _perfect_hit_false - _perfect_forgiven`。**禁止回退式(改别人的值)与拦截式(吞事件)**——两者均已由用户否决。 -3. 🔴 **`seal_missed` 事件照常发射**(卡① 合回前名 `flag_missed`——见顶部标识符形态通则),不得因本件改动改变发射时机或吞并事件,其它订阅方(危险直觉·守等)零感知。 -4. 🔴 **玩家面禁「雷」字**(奇物.md v3.15 命名纪律:插旗=封印、危险格风味=地下城陷阱/怪物巢穴)。本批新增的 `feats.tres` 行 desc 与任何 UI 字符串不得含「雷」。 -5. 🔴 **四词表封闭**:新增 effect kind 必须同步进 `EFFECT_KINDS` 并在解释器 switch 加分支,否则行校验致命。 -6. 🔴 **`domain=battle` 显式写出**:该行将是 `feats.tres` 首例 battle 域(现役 29 行全为 adventure 或不写),须在数据行与代码注释双处留痕,防止后来者误读为缺省。 -7. 🔴 **改总量=重裁**:`TIER_QUOTAS` 总量变动是结构锚。用户已裁「净删」(rare 9→7/总量 104→102),本批不得自行把令牌转给别件来保住总量。 -8. 🔴 **本批与迭代 31 卡①串行同迭代**(v1.1 订正实证陈述):卡① 改标识符与玩家面字符串。**字段集不重叠**(卡① 不动 `CURIO_KINDS`/`TIER_QUOTAS`/`curio_*`),但**文件集重叠**——`core/effect_engine.gd`(卡① 改 EVENTS/本卡 T4 加 EFFECT_KINDS+switch)、`core/settlement/grant_segment.gd`(卡① 改名/本卡 T4 改判定式)、`core/battle_orchestrator.gd`(卡① 改名/本卡 T3 删 `_fx_insurance`)。故**禁两卡并行开 worktree**;本卡必须在卡① 合回 master 后开工,开工前 `git merge master` 取卡① 成果并按顶部通则复核标识符名与行号。 - ---- - -## 4. 范围边界 - -**做**:上列 6 项完成定义内的全部代码与数据表改动、测试更新、`reports/` 三份产出物(实现报告/代拍板追认单/反哺点清单)。 - -**不做**(去向明确): - -| 不做的事 | 去向 | -|---|---| -| 计数器寿命域统一(三套机制并存问题) | 已在 06 登记「计数器寿命域未统一」,本批不动 | -| `entities.yaml:254`「完美排雷」内部术语改名 | 内部开发用语按 v3.15 纪律保留;仅玩家面用「完美封印」 | -| 冒记遗留两项(凭证归专长/资源=转换源判据句)的正式裁定与重写 | 06 已登记「冒记案遗留待裁两项」,等用户裁 | -| `shop.tres` 货架行、`feat_ticket` 体系 | 与本批无关,不碰 | -| 旧 27 件素材库表 | 不碰 | - ---- - -## 5. 关联文档同步面 - -> **口径(v1.1,2026-10-17 起生效)**:本批禁写 `design/` 整目录与根规则文件,唯一可写目录=`reports/`。凡标「反哺点」者=把「哪个文件哪一节、改成什么、依据是什么」写进 `reports/iter31-反哺点-<日期>.md`,由用户裁决后归文档批落笔。v1.0 的「机械面随批」措辞作废(属 2026-10-17 改口径前的旧口径)。 - -| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 | -|---|---|---| -| `design/gdd/systems/冒险循环/奇物.md` | v3.18 已定稿删件/迁出;本批代码落地后,件表注与迁入登记段中「归独立批」的指针可销号 | **反哺点**·列清单(`design/` 内,本批禁写) | -| `design/registry/entities.yaml:633` | 「104 总量」读数须改为 102(当前注记明写"仍为代码现值,改数随独立代码批同步");:254 完美排雷判据句须补「有效误标=误标数−豁免数」口径 | **反哺点**·列清单(含两处:104→102 读数换代+判据句补写) | -| `design/gdd/07-体验验证清单.md` | 两件退出后相关观测项注销;本卡新增 R5/R6 目检项(专长卡面文案/三选一池面观感)入册 | **反哺点**·列清单(本批禁写 07;R5/R6 目检项先记 `reports/` 实现报告总清单) | -| `roadmap.md` | 迭代 31 行状态由「待开工」改「已完成」;顶部「当前位」三行换代 | **反哺点**·列清单(根规则文件,本批禁写;第 3 步搬运定义面除外——那是提交既有文件,不是本批撰写) | -| `game/README.md` | 若载有两件名或配额读数 | **本批直改**(文件在 `game/` 内,不属 `design/` 禁写面)——随批核对更新 | -| `design/gdd/06-待办清单.md` | 「凭证件裁削批·代码侧迁移」条目状态推进为已完成 | **反哺点**·列清单(本批禁写;§10 前置门 2 的推进归用户/文档批) | -| GDD 设计结论 | **零新增**——设计侧已在 v3.18 定稿,本批无新设计决策需反哺 | 无(上述五行是既有陈述的换代,不是新设计) | - ---- - -## 6. 任务卡 - -| 卡 | 内容 | 估时 | -|---|---|---| -| **T0 开工基线** | 建 worktree+分支;`git status` 归属核对(并行遗留只标旗不碰);跑冒烟/单元/探针/三闸基线并记档;确认卡①是否已合回(若未合回,本批基于当前 master 开工并登记) | 0.25–0.5d | -| **T1 同调电池·表侧删除** | `CURIO_KINDS` 移除 kind;删 `curio_quota_attune_battery_rare`/`curio_value_attune_battery_rare`/`curio_cap_attune_battery` 三字段及分发表三处分支(:138/:159/:176);同步 schema 头注(:19-20 五件入池表述) | 0.25–0.5d | -| **T2 同调电池·runner 侧删除** | 删 `_battery_pending`、断点回填(:213)、重置(:261)、路由分支(:415-417)、`choose_battery_target`(:598-610)、`battery_pending()`(:615-616)、断点键(:1076);`feat_vouchers_test.gd` V9-5 断言组整组删 | 0.25–0.5d | -| **T3 完美保险·出池** | `CURIO_KINDS` 移除 kind;删配额/件值/cap 三字段与分发表三处分支;删 runner 侧 `_pending_insurance`、重置、路由分支、战首注入链(:920-923)中该件分量;删 `battle_orchestrator._fx_insurance` 与 `:422` 注入;`feat_vouchers_test.gd` V9-4 断言组整组删 | 0.5–1d | -| **T4 引擎扩签+两账相减** | `EFFECT_KINDS` 增 **`forgive_seal_miss`**(v1.1 换代,原 `forgive_flag_miss`);解释器 switch 加分支;`battle_orchestrator` 增 `_perfect_forgiven`(install 重置同 :471-472);`grant_segment` 判定改 `effective_miss = _perfect_hit_false - _perfect_forgiven`,删硬编码 if;`seal_missed` 发射位置与时机不动(卡① 合回前该事件名仍为 `flag_missed`) | 0.5–1d | -| **T5 专长行落表** | `feats.tres` 增完美保险行(规格=§10 D2,已裁:rarity rare/cap 省略/desc「本场首次封印落空,不计入完美封印判定」/feat_id 取 `perfect_insurance`);**触发行 `on` 取 `"seal_missed"`**(卡① 合回前该名仍为 `flag_missed`)、`kind` 取 `forgive_seal_miss`、`domain=battle` 显式写出;`feat_table` 校验通过;确认 rebuild 装载并在 `_triggers` 出现 | 0.25–0.5d | -| **T6 配额重裁落地** | `TIER_QUOTAS` rare 9→7、总量 104→102;`validate()` 硬断言通过;`adventure.tres` 实例值同步;核对 rare 档剩余品种=ap/rap/time_sand 三种 | 0.25d | -| **T7 测试补齐** | 新增专长侧验收(见验证闸);变异验证逐条执行并记录 | 0.5–1d | -| **T8 产出物落位卡+代码域闸** | 轻闸全绿后:`reports/` 三份写齐——实现报告(各 T 卡状态+改前改后读数对拍+实机目检总清单含 R5/R6+变异验证记录表)、代拍板追认单、**反哺点清单**(§5 每条都要有落点:奇物.md 指针销号句、entities.yaml 104→102 与 :254 判据句、07 观测项换代、roadmap 迭代 31 行与「当前位」换代、06 本条状态推进句、术语表 `forgive_seal_miss`/`seal_missed` 换代);`game/README.md` 属 `game/` 内文件、本批直改核对;跑代码域闸全绿。**禁改 `design/` 与 `roadmap.md`** | 0.25–0.5d | - -**合计**:≈2.75–4.75d(超软盒预案:T3/T4 若撞断点兼容问题,先落 T1/T2/T6 的可独立验证部分,T3–T5 转下一批并登记 06)。 - ---- - -## 7. 验证闸(逐需求点验收) - -### 7.1 逐需求点验收清单 - -| 需求点 | 测什么 | 测试落点 | 归谁验 | -|---|---|---|---| -| R1 电池出池 | `_apply_curio_pick("attune_battery", ...)` 不再被受理;三选一候选集不含该令牌;`CURIO_KINDS` 无该值 | 单元:`adventure_table` 词表断言+`feat_vouchers_test` 反例断言(改后应变红→改为断言"不再受理") | 调试接口 | -| R1 电池无孤儿 | `choose_battery_target`/`battery_pending()` 符号不存在(编译级);断点存档结构无 `battery_pending` 键;旧断点档缺键不报错 | 单元:断点 roundtrip 测试(save_rng_roundtrip 或既有断点套)加缺键兼容断言 | 调试接口 | -| R1 账本保留 | `_seed_attune_charges` 仍每冒险重置主动件充能;`run_ledger.attune_charges` 语义不变 | 单元:既有冒烟断言复核+补一条"删件后充能账本仍按装备重置" | 调试接口 | -| R2 专长行合法 | `feats.tres` 新行通过 `FeatTable.validate`;`EffectEngine.rebuild` 装载后 `_triggers` 含该行两段 | 单元:`effect_words` 类测试加行断言 | 调试接口 | -| R2 豁免一次 | 同战两次标错:首次 `effective_miss` 不增、第二次增;跨战后首次标错又豁免一次(domain=battle 每战清零) | 单元:直构引擎+编排 rig(参照 `smoke_all.gd:6091` 守侧五场景的 rig 法) | 调试接口 | -| R2 计数纯净 | 触发豁免后 `_perfect_hit_false` **值不变**(仍是误标原值);`_perfect_forgiven` 单向 +1 | 单元:同上 rig,双值对拍断言 | 调试接口 | -| R2 判定正确 | `_perfect_hit_false=2 / _perfect_forgiven=1` → effective 1 → 不完美;`1/1` → 完美成立;`_perfect_hit_true=0` 时不成立 | 单元:真值表断言 | 调试接口 | -| R2 事件不吞 | 触发豁免的同一标错,`seal_missed`(卡① 合回前名 `flag_missed`)仍被其它订阅方收到(以危险直觉·守的 AP 返还为观测点) | 冒烟:复用既有守侧场景 | 调试接口 | -| R3 配额锚 | `validate()` 通过;rare 合计 7;总量合计 102;rare 品种集={ap, rap, time_sand} | 单元:`adventure_table` validate 断言 | 调试接口 | -| R4 词表合法 | 新 kind 在 `EFFECT_KINDS`;数据行 do.kind 出域即加载致命(反例实证) | 单元:词表成员断言 | 调试接口 | -| R5 玩家面文案 | 新行 desc 不含「雷」;卡面显示正常 | 用户目检(登记 07) | 用户目检 | -| R6 池面观感 | 三选一再不出现两件;稀有档仅剩三种 | 用户目检(登记 07) | 用户目检 | - -### 7.2 变异验证伴生(新增/改写断言必配) - -| 变异点 | 注入形态 | 跑哪道最窄闸 | 期望红 | -|---|---|---|---| -| 两账相减判定 | 把 `effective_miss` 改回 `_perfect_hit_false`(漏减豁免) | 单元:真值表那条 | 「1/1 → 完美成立」变红 | -| 计数纯净 | 把豁免实现改回退式(`_perfect_hit_false -= 1`) | 单元:计数纯净断言 | 「_perfect_hit_false 值不变」变红 | -| 限次 | 把 `when` 的 `lt 1` 改成 `lt 99` | 单元:豁免一次断言 | 「第二次标错不豁免」变红 | -| domain=battle | 把 `domain` 改成 `adventure` | 单元:跨战豁免断言 | 「跨战不再豁免」变红 | -| 配额锚 | 把 rare 合计改回 9(漏删一张) | 单元:validate 断言 | 「rare 合计 7」变红 | -| 电池出池 | 把 kind 加回 `CURIO_KINDS` | 单元:词表断言 | 「CURIO_KINDS 无该值」变红 | - -### 7.3 闸口径 - -轻闸(每轮):`tools/run_all_gates.sh --quick`。重闸(批末):`tools/run_all_gates.sh --code`(本批只碰 `game/` 与 `tools/`)。批末四闸=冒烟+单元测试+场景探针+改前改后读数对拍,全绿才合并。 - ---- - -## 8. 异常分级 - -- **L1 自救**:字段删除后编译报错(漏改引用)——按报错定位补齐,属本批范围。 -- **L2 记录继续**:旧断点档含 `battery_pending` 键(缺键兼容路径已验证不报错);`adventure.tres` 实例字段与 schema 不同步导致加载警告——记录后继续,批末统一核对。 -- **L3 停机写报告**:①删 `attune_charges` 账本被误触(契约 1);②四词表校验出现非预期致命(说明扩签方式与引擎假设冲突);③T3/T4 触断点版本兼容须迁移(本批无迁移授权);④卡①未合回且其改动与本卡文件集出现意外重叠。 - ---- - -## 9. 代拍板白名单 - -1. `feat_id` 取 `perfect_insurance`(与旧 kind 同名,便于追溯旧讨论);display_name 取「完美保险」。 -2. 豁免计数 `counter_id` 命名取 `insurance_used`(与 `tree_*_used` 同族)。 -3. 若核出 `DO_KEYS.cap` 语义适用于"本 effect 累计上限",则省掉第二条 `counter_add` 触发行(外部行为等价,单行更简);核不出则维持双行。**须在实现报告注明最终选型与依据**。 -4. 测试文件落点:能并进 `feat_vouchers_test.gd` 就并,不新建套件(避免套件数膨胀)。 -5. `_perfect_forgiven` 的 install 重置点紧随 `:471-472` 既有重置,不新设重置钩子。 - -超清单必呈报。 - ---- - -## 10. 待裁点(2026-10-18 已裁毕;开工门=U0) - -- ✅ **D1 效果类型命名**=`forgive_flag_miss`(用户裁「合动宾惯例的」)→ **v1.1 换代为 `forgive_seal_miss`**(2026-10-18 用户补裁)。原裁定管的是命名形状(动词+宾语,与 EFFECT_KINDS 现役 `add_ticket_rider`/`modify_ticket`/`damage_mult` 同族),不是 flag/seal 之争;卡① 要求 `game/` 内 `flag` 零命中,故新名取 seal 族。 -- ✅ **D2 专长行规格**=`rarity` 取 `rare`/`cap` 省略(承 twin_pick/geologist 惯例)/`desc`=「本场首次封印落空,不计入完美封印判定」(用户确认,沿用 A 案)。 -- ✅ **D3 roadmap 目标句措辞**=维持现落地的「两卡串行:卡①代码术语刷新批+卡②凭证件裁削批·代码侧」事实式表述(用户裁「没有问题」)。 - -**开工门**:用户发开工令(U0)+**两项前置门(v1.1 补列,2026-10-18 卡片冲突修订批核出)**—— - -1. **卡① 已合回 master**(本卡所有 flag_ 旧名要按 seal_ 形态复核,且 T3/T4 与卡① 同改三文件,见契约 8); -2. **设计事实源已进 HEAD**(2026-10-18 本会话复核:本门**已满足**):`design/gdd/systems/冒险循环/奇物.md` v3.18 已随提交 `39523dd4` 进 master,`HEAD:奇物.md` 含 v3.18,worktree 从 HEAD 检出读得到本卡事实源。06「凭证件裁削批·代码侧迁移」状态列也已由「待写卡」推进为「文档设计已闭合(奇物.md v3.18)+已写卡(本卡路径)+已编迭代 31」。 - -本卡不等冒记遗留两项(凭证归专长/资源=转换源判据句)的裁定——那两项不阻塞本卡。 diff --git a/roadmap.md b/roadmap.md index 65080a92..250ebc0e 100644 --- a/roadmap.md +++ b/roadmap.md @@ -5,8 +5,8 @@ ## 当前位(只回答「现在该做什么」;三行内随批次换代,禁止在此扩写成状态快照) - **阶段**:M3——Alpha 版本的完整实现(2026-10-09 立规:未明令宣布完成前停留 M3,迭代只排 M3 需求,M4 不排期;根目录 stage.txt 为旧阶段开关仅存档)。 -- **迭代位**:迭代 1–30 全部已完成或已终止;**迭代 31 待开工**(两卡串行:卡①代码术语刷新批+卡②凭证件裁削批·代码侧,均 2026-10-18 编入)。 -- **下一步**:迭代 31 开工令(U0)归用户发。其余候选在 06 状态列——营地交互重做五卡(已写卡待编迭代)、迭代 30 原卡②③(待美术/设计定稿后重新立卡)。 +- **迭代位**:迭代 1–31 全部已完成或已终止;下一迭代位待用户编排。 +- **下一步**:06 在册候选——营地交互重做五卡(已写卡待编迭代)、迭代 30 原卡②③(待美术/设计定稿后重新立卡)、玩家面残留禁字清扫(待写卡)。 ## 里程碑时间线 @@ -64,7 +64,7 @@ | 迭代 28 | 已完成(2026-10-15) | 已退役(git 历史可考) | 2026-10-15 | — | 已退役(git 历史可考) | | 迭代 29 | 已完成(2026-10-16) | 已退役(git 历史可考) | 2026-10-16 | — | 已退役(git 历史可考) | | 迭代 30 | 已完成(2026-10-17) | 已退役(git 历史可考) | 2026-10-16 | — | 已退役(git 历史可考) | -| 迭代 31 | 待开工 | reports/需求卡片-代码术语刷新批-2026-10-18.md、reports/需求卡片-凭证件裁削批-2026-10-18.md | 2026-10-18 | ≈1.5 周 | — | +| 迭代 31 | 已完成(2026-10-19) | 已退役(git 历史可考) | 2026-10-18 | ≈1.5 周 | 已退役(git 历史可考) | - 历史行的「—」= 该列事实不可考:迭代 1~8 早于需求卡片制;编排时点与预计周期不再回溯,细节查 git 提交史。 - 「已退役(git 历史可考)」= 需求卡片或实现报告曾存在,已按「证据只留最新」退役;已完成迭代的实现报告列只填 reports/ 现存路径或本保留字,不填「—」。 From 3304850d1797d15e3944c5fbd3d543e52a317e85 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 18:56:21 +0800 Subject: [PATCH 18/59] =?UTF-8?q?docs(=E6=95=88=E6=9E=9C=E5=BC=95=E6=93=8E?= =?UTF-8?q?=E6=97=A0=E7=8A=B6=E6=80=81=E5=8C=96=C2=B7=E5=A4=8D=E6=A0=B8?= =?UTF-8?q?=E8=A3=81=E5=86=B3=E5=85=A5=E5=8D=A1):=20=E5=AF=B9=E6=8A=97?= =?UTF-8?q?=E5=A4=8D=E6=A0=B8=E5=85=AD=E9=A1=B9=E8=A3=81=E5=B9=B6=E5=86=99?= =?UTF-8?q?=E8=BF=9B=E6=AD=A3=E6=96=87=E2=80=94=E2=80=94V12=20=E5=A4=8D?= =?UTF-8?q?=E6=94=BE=E5=9F=BA=E7=BA=BF=E6=94=B9=E6=89=B9=E5=86=85=E9=87=8D?= =?UTF-8?q?=E9=87=87=EF=BC=88=E6=89=B9=E5=89=8D=E4=B8=89=E7=BB=84=2040=20?= =?UTF-8?q?=E5=B1=80=E5=B7=B2=E9=87=87=E5=AE=8C=E7=95=99=E7=9B=98=E5=B8=A6?= =?UTF-8?q?=E5=93=88=E5=B8=8C=E3=80=81=E6=89=B9=E5=90=8E=E5=90=8C=E7=A7=8D?= =?UTF-8?q?=E5=AD=90=E5=A4=8D=E6=94=BE=EF=BC=8C=E7=8E=B0=E8=A1=8C=E9=94=9A?= =?UTF-8?q?=2024=20=E5=AD=97=E6=AE=B5=E9=9D=A2=E4=B8=8E=E7=8E=B0=E9=87=87?= =?UTF-8?q?=2033=20=E5=AD=97=E6=AE=B5=E9=9D=A2=E4=B8=8D=E5=90=8C=E6=9E=84?= =?UTF-8?q?=E6=95=85=E5=88=A4=E5=BA=9F=EF=BC=89=EF=BC=9B=E5=89=8D=E7=BC=80?= =?UTF-8?q?=E5=88=A4=E6=8D=AE=E9=87=87=E6=9D=BE=E7=89=88=EF=BC=8B=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E8=A3=85=E8=BD=BD=E6=9C=9F=E5=BC=95=E7=94=A8=E9=97=AD?= =?UTF-8?q?=E5=90=88=E6=A0=A1=E9=AA=8C=EF=BC=88feats.tres=20=E7=8E=B0?= =?UTF-8?q?=E6=9C=89=2014=20=E6=9E=9A=20id=20=E5=85=A8=E5=90=AB=E4=B8=8B?= =?UTF-8?q?=E5=88=92=E7=BA=BF=EF=BC=8C=E5=B0=81=E9=97=AD=E5=89=8D=E7=BC=80?= =?UTF-8?q?=E8=AF=8D=E8=A1=A8=E8=AF=AF=E4=BC=A4=E6=97=A2=E6=9C=89=20battle?= =?UTF-8?q?=20id=EF=BC=89=EF=BC=9B=E6=94=B9=E5=90=8D=E9=9D=A2=E6=89=A9?= =?UTF-8?q?=E5=88=B0=E8=AF=BB=E7=82=B9=20:39/:501=E3=80=81=E5=90=88?= =?UTF-8?q?=E6=88=90=E8=A1=8C=E4=B8=8E=E5=A4=B9=E5=85=B7=E7=9A=84=20domain?= =?UTF-8?q?=20=E6=AE=8B=E7=95=99=E3=80=81=E4=B8=83=E5=A4=84=E8=BF=87?= =?UTF-8?q?=E6=9C=9F=E6=B3=A8=E9=87=8A=EF=BC=9Bpain=5Flayers=20=E6=8E=AA?= =?UTF-8?q?=E8=BE=9E=E6=94=B9=E3=80=8C=E5=8D=95=E6=88=98=E9=9B=B6=E5=8F=98?= =?UTF-8?q?=E6=9B=B4=EF=BC=8B=E6=97=A7=E6=A1=A3=E7=BB=AD=E7=8E=A9=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E8=B7=A8=E6=88=98=E3=80=8D=E5=88=97=E7=AC=AC=E4=B8=89?= =?UTF-8?q?=E5=A4=84=E9=A2=84=E6=9C=9F=E5=B7=AE=E5=BC=82=EF=BC=9BV1/V5/V9?= =?UTF-8?q?=20=E5=A4=B9=E5=85=B7=E5=86=99=E6=AD=BB=E3=80=81V9=20assert=20?= =?UTF-8?q?=E4=BE=A7=E6=B3=A8=E5=85=A5=E7=82=B9=E6=94=B9=E7=9B=B4=E8=B0=83?= =?UTF-8?q?=20=5Fpush=5Ftrigger=EF=BC=9B=E9=87=87=E9=9B=86=E5=99=A8=20rule?= =?UTF-8?q?s=20=E6=B3=A8=E5=85=A5=E7=B1=BB=E5=9E=8B=E7=BC=BA=E9=99=B7?= =?UTF-8?q?=EF=BC=88split=20=E4=BA=A7=E5=87=BA=20PackedStringArray=20?= =?UTF-8?q?=E8=A2=AB=20is=20Array=20=E9=9D=99=E9=BB=98=E4=B8=A2=E5=BC=83?= =?UTF-8?q?=EF=BC=89=E4=BF=AE=E5=A4=8D=E5=88=97=E4=B8=BA=20T0=20=E9=A6=96?= =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../需求卡片-效果引擎无状态化批-2026-10-20.md | 146 ++++++++++++------ 1 file changed, 96 insertions(+), 50 deletions(-) diff --git a/reports/需求卡片-效果引擎无状态化批-2026-10-20.md b/reports/需求卡片-效果引擎无状态化批-2026-10-20.md index 7e8fcc1e..8d6449ac 100644 --- a/reports/需求卡片-效果引擎无状态化批-2026-10-20.md +++ b/reports/需求卡片-效果引擎无状态化批-2026-10-20.md @@ -3,8 +3,8 @@ - **日期**:2026-10-20 - **来源**:06-待办清单「计数器寿命域未统一」条目(2026-10-18 登记,来源=会话提及,设计面=文档轨),设计已闭合推进至待写卡(唯一事实源:`design/research/提案-效果引擎无状态化-2026-10-19.md` v1.2——§3 目标形态、§7 N1–N6 定值、§7.7 采集定值、§7.10 缺口闭合定值) - **批性质**:工程直入类·架构重构(restructure)——代码域批,禁写 `design/` 整个目录与根规则文件,产出物只落 `reports/` -- **估时**:≈3.75–5.75d(T0–T8 单卡;超盒切分预案=T7 拆「断言新增/迁移」与「复放比对」两波先后挂,T3 与 T7 测试迁移互不阻塞可并行切) -- **状态**:成文待审——零待裁点,开工门=U0(用户发令) +- **估时**:≈4.5–6.25d(=T0–T8 加总;超盒切分预案=T7 拆「断言新增/迁移」与「复放比对」两波先后挂,T3 与 T7 测试迁移互不阻塞可并行切) +- **状态**:成文待审——零待裁点(对抗复核六项已裁并并入正文,见 §12),开工门=U0(用户发令) --- @@ -18,8 +18,8 @@ 2. 计数器四桶外置:round/battle 桶挂 `BattleOrchestrator`、level 桶挂 `LevelRunner`、adventure 桶挂 `run_ledger.adventure_counters`,桶随宿主生灭; 3. 搬运链整段删除:`counters_export`/`counters_seed`(引擎)与 `counters_seed_snapshot`/`counters_merge_export`(RunLedger)零残留; 4. `adventure_runner.gd:838-841` 硬编码清除名单(`_reset_tree_limited_counters`)删除,按关清零由 LevelRunner 每关 new 天然承载; -5. 计数器归属机器可读且加载期可校验:`.tres` 行(errs→加载致命)与树合成行(`_push_trigger` assert)双落点,写错前缀即致命; -6. 同种子复放比对按分组判读通过(V12):未受影响局 RUNSUM 全字段逐位一致;受影响局输入面字段恒等+`levels_cleared` 分布不得上行——**不声称零漂移**(adventure 桶跨战持久与天赋树每关限次是已定性预期差异,提案 §7.7/§7.8); +5. 计数器归属机器可读且加载期可校验:`.tres` 行(errs→加载致命)与树合成行(`_push_trigger` assert)双落点,写错前缀即致命;另加装载期**引用闭合**——凡被读到的计数器 id(`when` 内 `fact: counter` 的 `id`/`do.value_counter`/`counter_spend` 的 `counter_id`)必须能在声明集(feats 行+秘宝行+树合成行的 `do.counter_id`)里找到同名写入行,找不到即加载致命; +6. 批内同种子复放比对按三组判读通过(V12):**off 组**(`feat_mode=off`)RUNSUM 全字段逐位一致;**formed 组**(`formed`)与 **rules 组**(`rules`+sense 两键)输入面字段与字段集恒等、局数与种子集一致、零崩溃;输出面差异与 `levels_cleared` 方向只记报告不作判据——**不声称零漂移**(三处已定性预期差异见契约 1); 7. `dig_combo` 死读数连同 combo 分支删除,零行为差(§7.10.14); 8. 旧档断点含旧计数键加载不崩(V13,无迁移——2026-10-18 代码术语刷新批先例)。 @@ -28,11 +28,13 @@ `design/research/提案-效果引擎无状态化-2026-10-19.md` **v1.2**(2026-10-20 设计闭合版)——本卡全部设计定值的唯一出处: - 目标形态与四桶表=提案 §3(3.1 宿主定值/3.2 接口定稿/3.3 前缀归属); -- N1–N6 定值=提案 §7;不发起全冒险模拟采集=提案 §7.7(零数值改动=零采集,本批一个数值表值都不改);搬运链缺陷全解=提案 §7.8; +- N1–N6 定值=提案 §7;不发起全冒险模拟采集=提案 §7.7(零数值改动=零采集——本批唯一例外是 V12 的复放采集,见 §12 裁点①);搬运链缺陷全解=提案 §7.8; - 写卡前缺口闭合定值=提案 §7.10(ctx 结构/容器类型与测试接口/前缀校验双落点/写口静态化/施加面补列/改名传播面/保险双账不改面/A1 注入口径/level 桶接口/复放分组判读/mine_hit 构造/dig_combo 删除/H1 补条)。 与 06 条目状态里的闭合凭据一致(v1.2)。 +**与本卡口径不一致的提案节以本卡为准**,三处冲突及裁决见 §12:§7.10.3 前缀判据(封闭词表方案在现实 id 面上误伤全部既有 battle id)、§7.10.12 复放判读(所记 27 字段与实采 33 字段不符,且单一「不得上行」判据把增强组与削弱组混判)、§7.7 零采集定值(现行锚与本批不同构,不可用作复放基线)。实现批禁写 `design/`,三处订正随反哺点清单归文档批。 + ## 3. 现状事实(2026-10-20 代码级实查,开工自行复核) **引擎侧**: @@ -50,27 +52,35 @@ **死路**:`battle_orchestrator.gd:635-647` `_feat_yield_adjust` 读 `dig_combo`(全仓无数据行声明——feats.tres/treasure_items.tres/树合成行三源零命中;feats.tres 唯一 `"cap"` 行属石肤 ac_bonus `:576-583`,yield_mult 带 cap 行零个)⇒ `combo_val` 恒 0、`combo_cap` 恒 ≤0,分支恒短路。 -**数据行**:`feats.tres` 计数 id 共 14 枚+树合成 2 枚=16 枚;`reset_at: round_start` 恰 4 行(`round_blast_spent` :212/`instinct_atk` :494/`round_mines` :518/`round_digs` :723——全带 round_ 前缀或随改名获得前缀,分桶后「整桶清空」与现役名单清零逐键等价);`domain` 键行:`twin_digs` :31/`pain_layers` :377/:535/:628(另 :407 附近 set 行)/`insurance_used` :877(battle)。 +**数据行**:`feats.tres` 计数 id 共 14 枚+树合成 2 枚=16 枚,**14 枚全含下划线**(`round_digs`/`round_mines`/`round_blast_spent` 三枚既有 id 已自带 `round_` 前缀);`reset_at: round_start` 恰 4 行(`round_blast_spent` :212/`instinct_atk` :494/`round_mines` :518/`round_digs` :723——三枚 round_ 前缀行现役已按轮始清零、改名零涉及,分桶后「整桶清空」与现役名单清零逐键等价);`domain` 键行:`twin_digs` :31/`pain_layers` :377/:535/:628(另 :407 附近 set 行)/`insurance_used` :877(battle)。**写点与读点成对同名**:`twin_digs` 写 :29/读 `when.id` :39;`instinct_atk` 写 :492/读 `value_counter` :501——改名必须成对同改,只改写点会把读写拆进两只桶且前缀校验查不出。 + +**残留 `domain` 键两处**:`effect_engine.gd:145/:155` 树合成行与 `tree_rules_v11_test.gd:33/:39` 夹具行仍带 `"domain": "adventure"`——`DO_KEYS` 删键后该夹具在 `validate_trigger_row` 面当场转红,在 T6 一并清除。 + +**过期注释面**:`effect_engine.gd:42`(「feats.tres 首例 domain=battle 行」)/`:70-71`(domain 键说明)/`:118-120`(adventure 域计数器按关重置叙述)、`grant_segment.gd:307`(「限次=合成行 adventure 域计数器闸」——sense 两键改 level 桶后失义)、`run_ledger.gd:7-8` 与 `:12`(export/seed 时点语义、「rebuild 回灌/战末导出回写目标」字段注)、`level_runner.gd:630`(T1 已列)——分桶后字面全部失义,在 T6 一并清除。 + +**采集器与复放数据面(2026-10-20 实跑复核)**:现行锚 `runsum_m3iter9exit_81000_n400_20261003.jsonl` 是 24 字段面、无 `feat_mode`/`attune`/`equipped`/`seal_miss`,与现役采集器的 33 字段面不同构;`sim-data/` 整目录不入 git,批 worktree 内本就没有该文件——两条合起来判锚不可用作本批复放基线,改批内重采(T0/T7)。另查出采集器缺陷:`adventure_monte_carlo.gd:65` 的 `rules` 档用 `String.split()` 产出 `PackedStringArray`,被 `adventure_runner.gd:118/:200` 的 `is Array` 守卫整组静默丢弃——对照实跑为 `ab_a`(字面量 Array)逐局改变轨迹、`rules` 与 `off` 除 `feat_mode` 标签外逐位相同;不修此行则 V12 的 rules 组恒假绿(修复列 T0 首提交)。 + +**静态扫描面**:`static_scan.sh:20-24` 的扫描路径单点只有 `game/core` 与 `game/presentation`,`scan_files` 只数 `.gd`——`feats.tres`、`game/tests/`、`game/smoke/` 全不在面内,新 S 段必须自带扩面(T7),否则「全仓零命中」是空转出来的绿。 **测试面**:`tests/run_all.gd` manifest(负面套件协议 `expect:1`+`negative:true`,先例 `reward_dangling_treasure_test.gd` 夹具注入);`tests/README.md:58` 记套件数 26;`game/presentation/` 全目录 counter_id 与 16 枚 id 字面零命中(呈现层不入改名传播)。 ## 4. 设计契约(违反即返工;🔴 触碰=L3 停机呈报) -1. 🔴 **确定性**:除 V12 已定性的两处行为变更(adventure 桶真跨战持久、天赋树锋/守真每关限 2)外,同种子复放必须逐位一致——读写时序、装载序、命中序零变化;命中序=装载声明序写死不碰。 +1. 🔴 **确定性**:除三处已定性行为变更(①adventure 桶真跨战持久;②天赋树锋/守真每关限 2;③旧档续玩时 `pain_layers` 不再跨战携带——见契约 8)外,同种子复放必须逐位一致——读写时序、装载序、命中序零变化;命中序=装载声明序写死不碰。全新开局不受③影响(缺陷态下本就未跨战,提案 §7.8 自锁)。 2. 🔴 **数值零改动**:本批不改任何数值表值;天赋树锋/守「每战 2→每关 2」是回到设计意图(`effect_engine.gd:137` 注释),不是平衡调整;禁顺手调任何 provisional 值。 3. 🔴 **round 桶就地清空**:轮始清零必须 `.clear()`(或等效就地清空),**禁 `= {}` 重赋值**——重赋值会切断 ctx 持有的引用。 4. 🔴 **搬运链删除后禁留任何副本同步时点**:战末导出/战首回灌/判空守卫三类代码不得以任何形态复活(含「防御性保留」)。 5. 🔴 **保险双账不改面**:`_perfect_forgiven` 与 `insurance_used` 同点双记关系原样保持(§3 现状事实),禁合并、禁迁账、禁改判定段两账相减语义(N6 定值)。 -6. 🔴 **两落点同源**:前缀校验的判定函数唯一(静态单点),`validate_trigger_row` 与 `_push_trigger` 共用;禁两处各写一份前缀表。 +6. 🔴 **两落点同源**:前缀校验的判定函数唯一(静态单点),`validate_trigger_row` 与 `_push_trigger` 共用;禁两处各写一份前缀表。引用闭合校验(T5)只做「读点 id ∈ 声明集」的成员判定,**禁在其中再写一份前缀判据**——前缀归桶的唯一出处仍是 `bucket_of`。 7. 🔴 **容器与接口逐字锁定**:`EffectContext` 四字段名 `round_bucket`/`battle_bucket`/`level_bucket`/`adventure_bucket`;编排器成员 `fx_counters_round`/`fx_counters_battle`/`counters_ctx`;LevelRunner 成员 `level_counters`;enc 下传键 `"level_counters"`;改名 4 枚新 id `adv_twin_digs`/`lvl_tree_sense_sharp_used`/`lvl_tree_sense_guard_used`/`round_instinct_atk`。实现期不得另起名。 -8. 🔴 **pain_layers 归 battle 零语义变更**:只改归属(删 `domain` 键),「攒层→下次攻击附加→用后清零」行为逐位不变(N4)。 +8. 🔴 **pain_layers 归 battle**:只改归属(删 `domain` 键),单战内「攒层→下次攻击附加→用后清零」行为逐位不变(N4)。跨战口径按设计意图统一为「不跨战」:全新开局本就如此(`run_ledger.gd:42` 自锁),旧档续玩经 `adventure_runner.gd:206-208` 回灌后原可跨战携带,改后不再携带——该差异属缺陷消解(契约 1 第③项),不是语义回归,V13 旧档夹具须带 `pain_layers` 旧键。 9. 🔴 **旧档不迁移**:改名后旧档断点旧键成死键属预期(H1 只断言不崩);禁加迁移体、禁动 `SAVE_FORMAT_VERSION`。 -10. 🔴 **实现批禁写 `design/` 与根规则文件**;`sim-data/` 零采集零重跑(§7.7 定值——本批零数值改动,锚与读数不动)。 +10. 🔴 **实现批禁写 `design/` 与根规则文件**;`sim-data/` 只允许 V12 的两次采集(批前三组 40 局基线——已采完留盘,见 T0;批后同种子复放 40 局),二档上限内;现行锚与读数文件一律不动、不改名、不替换;对 `sim-data/README.md` 纪律③⑦的批次例外,依据见 §12 裁点①。 11. 🔴 **同名成员禁遮蔽内建**:ctx 字段名已避讳(`round_bucket` 非 `round`),实现期引入新成员时同规。 ## 5. 范围边界 -**做**:§1 完成定义 1–8 全部;`EffectContext` 新类;引擎接口 ctx 化与写口静态化;7 个施加点迁移;前缀校验双落点;4 枚 id 改名+`domain`/`reset_at` 键删除;`dig_combo` 死路删除;测试新增/迁移/变异验证;同种子复放比对(零局新采集,锚内子集 20 种子);`static_scan.sh` 新增 S 段+`run_all.gd` manifest 登记。 +**做**:§1 完成定义 1–8 全部;`EffectContext` 新类;引擎接口 ctx 化与写口静态化;7 个施加点迁移;前缀校验双落点+装载期引用闭合校验;4 枚 id 改名(写点与读点成对)+`domain`/`reset_at` 键删除(含引擎合成行与测试夹具两处残留);七处过期注释清扫;`dig_combo` 死路删除;采集器 `rules` 注入类型缺陷修复(一行,T0 首提交);测试新增/迁移/变异验证;批内同种子复放比对(三组 40 局基线已采+40 局复放+`tools/parity_compare.py` 判读);`static_scan.sh` 新增 S11 段(扫描面自带扩至 `game/**` 含 `.tres`)+`run_all.gd` manifest 登记。 **不做**(去向已定): @@ -82,7 +92,7 @@ | 天赋树锋/守重新定价 | 独立议题,不进本批(§4.5 B3) | | architecture.md「系统无状态」原则补条 | 已登记 06 新条目(文档轨·待文档设计),归文档批;本批反哺点带依据 | | `roadmap.md` 当前位 stale | 已呈报在案,归并行会话 | -| MC 采集(任何档位) | §7.7 定值:零数值改动=零采集 | +| MC 采集(V12 复放之外的任何档) | §7.7 定值:零数值改动=零采集——本批只跑 V12 的三组 40 局基线(已采完)与 40 局复放,不开任何读数档、不动现行锚与读数文件 | | 元素类型精化(`Dictionary[String, int]`) | S9 现行口径 `Dictionary[Variant, Variant]` 合格,精化另走裁决 | ## 6. 关联文档同步面(实现批禁写本表所列文档——义务全部走 `reports/iter-反哺点-<日期>.md`) @@ -93,7 +103,9 @@ | `game/tests/README.md` | :58 记「manifest 已登记实跑 26 套件」——本批新增 1 负面套件 | 反哺点(机械面文档,批后由文档批更新套件数与段描述) | | `design/gdd/06-待办清单.md` | 上游条目「计数器寿命域未统一」随批完成整条删除(收口=batch-closure 技能);条目现状内引用的行号(:838-841 等)随实现漂移 | 批内不动;收口时整条删除(行号订正随之消亡) | | `design/gdd/07-体验验证清单.md` | 天赋树锋/守第二次后无减免=玩家可感知削弱,需真人目检入册 | 反哺点(登记项见 §9 真人目检面) | -| `design/gdd/术语表.md` | 零关联(本批不造新术语;四桶/前缀均为代码标识符非玩家术语) | 无 | +| `design/research/提案-效果引擎无状态化-2026-10-19.md` | 三处与本卡口径不同(裁决见 §12):①§7.10.3「`meta_` 及其余未知前缀→违例」——14 枚 id 全含下划线,该判据误伤全部既有 battle id,且封闭前缀词表=第二事实源;②§7.10.12 记「RUNSUM 共 27 字段」且「受影响局 `levels_cleared` 不得上行」——实采 33 字段,且双管镐组是增强方向,单一判据把增强组与削弱组混判;③§7.7「零采集」定值所依赖的现行锚与本批不同构,不可作复放基线 | 反哺点清单逐条列出(本卡为准,提案随文档批订正;`design/` 对本批只读) | +| `sim-data/README.md` | 配套纪律③「对拍断言=0 新跑」与⑦「零数值改动=零 MC」在本批开例外(三组 40 局基线+40 局复放,二档上限内);「现行锚」节与本批复放无关 | 反哺点(登记批次例外与判据,不改档位表本身) | +| `design/gdd/术语表.md` | 零关联(本批不造新术语;四桶/前缀均为代码标识符非玩家术语;未新增 `battle_` 前缀词) | 无 | ## 7. 卡前文件结构图 @@ -102,26 +114,29 @@ | 文件 | 职责 | |---|---| | `game/core/effect_context.gd` | `EffectContext`——四桶引用束(RefCounted,四公开类型化字段,零方法) | -| `game/tests/unit/data_config/counter_prefix_fatal_test.gd` | E1 负面套件:坏前缀 counter_id 行 → load_tables 拒绝(expect 1) | +| `game/tests/unit/data_config/counter_prefix_fatal_test.gd` | E1 负面套件:坏前缀 counter_id 行→load_tables 拒绝 + 读点 id 无声明行(引用闭合)→load_tables 拒绝(expect 1,两断言同套件) | +| `tools/parity_compare.py` | V12 复放比对器:解析 `RUNSUM` 行按 seed 配对;`--mode parity`(整条记录逐位相等)与 `--mode input-parity`(输入面八字段+顶层字段集恒等)两判据;`--expect <局数>`;输出差异表与 `levels_cleared` 直方图(后者仅报告)。退出码 0 绿/1 红/2 用法或解析错;字段集从基线文件推导,禁硬编码 | **修改**: | 文件 | 改动 | |---|---| -| `game/core/effect_engine.gd` | 删三状态成员与搬运接口;dispatch/counter 带 ctx;写口改静态纯函数+`bucket_of`;`_push_trigger` 前缀校验;DO_KEYS 删两键;合成行(:136-155)id 改名 | +| `game/core/effect_engine.gd` | 删三状态成员与搬运接口;dispatch/counter 带 ctx;写口改静态纯函数+`bucket_of`;`_push_trigger` 前缀校验;DO_KEYS 删两键;合成行(:136-155)id 改名**并删 :145/:155 两处 `"domain": "adventure"`**;:42/:70-71/:116-122 过期注释改前缀口径 | | `game/core/battle_orchestrator.gd` | 两桶公开成员+ctx 构造挂载;set_fx 扩参;`dig_combo` 死路删除;战末导出两行删除 | | `game/core/action_economy.gd` | set_fx 扩参;3 dispatch 面+3 写口静态化 | | `game/core/damage_controller.gd` | set_fx 扩参;dispatch 汇聚面+1 读 2 写静态化 | | `game/core/reward_economy.gd` | set_fx 扩参;dispatch 面加 ctx | -| `game/core/settlement/grant_segment.gd` | `_apply_counter_hit` 静态化;2 读口 ctx 化;`combo_cap` 收集与实参删除 | -| `game/core/run_ledger.gd` | 删 `counters_seed_snapshot`/`counters_merge_export` | +| `game/core/settlement/grant_segment.gd` | `_apply_counter_hit` 静态化;2 读口 ctx 化;`combo_cap` 收集与实参删除;:307「限次=合成行 adventure 域计数器闸」注释改 level 桶口径 | +| `game/core/run_ledger.gd` | 删 `counters_seed_snapshot`/`counters_merge_export`;:7-8 头注契约句与 :12 字段注(「rebuild 回灌/战末导出回写目标」)改 ctx 直写口径 | | `game/core/adventure_runner.gd` | 删 `_reset_tree_limited_counters` 及调用点 | | `game/core/level_runner.gd` | `level_counters` 公开成员+enc `"level_counters"` 下传 | -| `game/data/tables/feats.tres` | 4 枚 id 改名;`domain`/`reset_at` 键逐行删除 | -| `game/tests/static_scan.sh` | 新增 S 段:旧件符号+带引号旧 id 字面零命中 | +| `game/data/tables/feats.tres` | 4 枚 id 改名(**写点 :29/:492 与读点 :39/:501 成对同改**);`domain`/`reset_at` 键逐行删除 | +| `game/core/config_db_cross_validator.gd` | 新增计数器引用闭合校验(声明集 vs 读点集,违例入 errs→加载致命) | +| `game/smoke/adventure_monte_carlo.gd` | `:65` `rules` 档类型修复(`split` 结果包 `Array(…)`、`split(",", false)`)——T0 首提交,V12 rules 组生效前提 | +| `game/tests/static_scan.sh` | 新增 S11 段:旧件符号+带引号旧 id 字面零命中;**扫描面自带扩至 `game/**/*.gd` 与 `game/data/tables/*.tres`**(现役 :20-24 只覆盖 core/presentation 的 `.gd`,不扩面即空转)+扫描面非空自检 | | `game/tests/run_all.gd` | manifest 登记负面套件 | | `game/tests/unit/core/effect_words_t1_test.gd` | ⑥ export/seed 块、⑦ reset_at/spend 块重写为桶语义;裸 dispatch/写口 ctx 化 | -| `game/tests/unit/core/tree_rules_v11_test.gd` | :29-39 合成行字面 id 随改名 | +| `game/tests/unit/core/tree_rules_v11_test.gd` | :29-39 合成行字面 id 随改名+**删 :33/:39 两处 `"domain": "adventure"`**(不删则 `validate_trigger_row` 面当场转红) | | `game/tests/unit/core/feat_vouchers_test.gd` | V16 键名随前缀;V25 迁移保绿;新增 H1 旧档不崩断言 | | `game/tests/unit/core/settle_segments_test.gd` | `:32-33` 样本 id 换活 id+ctx 形态 | | `game/tests/unit/core/treasure_effects_test.gd` | 裸 dispatch 面 ctx 化(:34/:45/:53-56) | @@ -132,7 +147,9 @@ ### T0 基线(0.25d) - [ ] worktree/分支开工(process-conventions §1);拷主区 `.godot/` 与字体 `.import` 边车 -- [ ] 基线三查记档:冒烟全绿数目、单元 26 套件全绿、探针基线;记录 `sim-data/` 现行锚文件名与 sha1(**只记录不跑**——零数值改动禁采集) +- [ ] **首提交=采集器 `rules` 注入类型缺陷修复**:`adventure_monte_carlo.gd:65` 的 `String(args[7] if args.size() >= 8 else "").split(",")` 改为 `Array(String(args[7] if args.size() >= 8 else "").split(",", false))`(不包则 `PackedStringArray` 被 `adventure_runner.gd:118` 的 `is Array` 整组静默丢弃——实测 `rules` 档与 `off` 逐位相同);单独一个提交,提交信息注明「测试工具类型修复,无玩法改动」 +- [ ] 基线三查记档:冒烟全绿数目、单元 26 套件全绿、探针基线 +- [ ] **V12 批前基线=卡片成文后的准备阶段已采完,批内不重跑**:三组文件(`sim-data/v12_base_off_n20_81000_f75acc1.jsonl` 20 局 81000–81019,sha256 `bf084ef3…`/`sim-data/v12_base_formed_n10_81000_f75acc1.jsonl` 10 局 81000–81009,sha256 `2d3d4247…`/`sim-data/v12_base_rules-sense_n10_81000_f75acc1_p1.jsonl` 10 局 81000–81009,sha256 `0fcbcb26…`,`_p1` 后缀=依赖上一条采集器修复),主区 `sim-data/` 与卡片 worktree `sim-data/` 两处留盘(`sim-data/` 不入 git,实现批新 worktree 内无此目录——开工时从主区拷入本 worktree 的 `sim-data/`,或让比对器按绝对路径读主区文件);采集时工作区无改动,有效码=commit `826e7ea1` 的 `game` 树 `f75acc15…` +本 T0 首提交。**开工先核 `git rev-parse HEAD:game`**:若不等于 `f75acc15…`(master 的 `game/` 在准备阶段之后前进过),留盘基线作废,按 T7 命令重采三组 40 局 - [ ] `git log --oneline -1` 与 `tools/run_all_gates.sh --code` 基线档记档(起点绿态) **产出**:基线档(实现报告 T0 节)。 @@ -182,67 +199,81 @@ - [ ] 确认 battle/level 桶零显式清零代码(宿主 new 天然空);全仓 grep `_reset_on_round_start`/`_adventure_counter_ids`/`_reset_tree_limited_counters` 零命中 - [ ] 孤立验证:round 桶写非零→dispatch("round_start")→整桶空;battle 前缀键同一 dispatch 下不动 -### T5 前缀校验双落点(0.25d) +### T5 前缀校验双落点+引用闭合(0.5d) -**取用**:T2 的 `bucket_of` 前缀规则。**产出**:加载期前缀致命通道(V9)。 +**取用**:T2 的 `bucket_of` 前缀规则。**产出**:加载期前缀致命通道+读点无声明致命通道(V9 两侧)。 -- [ ] 新增静态判定函数 `static func counter_id_legal(counter_id: String) -> bool`(名字锁定;规则=提案 §3.3 字面):`round_`/`lvl_`/`adv_` 前缀=true;`meta_` 前缀=false(引擎不接存档级);其余=true(无前缀落 battle——「其余未知前缀也非法」在语法上不可判定:一切 snake_case id 都以「词_」形态开头,禁自造封闭词表=第二事实源红线;自造新前缀静默落 battle 的残余风险由 V10 扫描与评审承担) +- [ ] 新增静态判定函数 `static func counter_id_legal(counter_id: String) -> bool`(名字锁定;判据见提案 §3.3 与 §12 裁点②):`round_`/`lvl_`/`adv_` 前缀=true;`meta_` 前缀=false(引擎不接存档级);其余=true(无前缀落 battle——「其余未知前缀也非法」在语法上不可判定:`feats.tres` 现有 14 枚 id 全含下划线,除三枚已带 `round_` 前缀外首段全是普通词(`pain_`/`geo_`/`helm_`…),封闭前缀词表会把它们全部判成违例,且自造词表=第二事实源红线)。自造新前缀静默落 battle 的残余风险由下条引用闭合校验(拦写读不一致)与 V10 扫描承接,不再单靠人工评审 +- [ ] **引用闭合校验**落 `config_db_cross_validator.gd`(既有跨表校验面,非单行校验):三源装载完成后收集声明集=各行 `do.counter_id` ∪ 树合成行 `do.counter_id`;再遍历全部读点(`when` 内 `fact: counter` 的 `id`、`do.value_counter`、`counter_spend` 的 `counter_id`),读点 id 不在声明集→errs 追加 `{"category": "enum", ...}` 违例→加载致命。判据只做成员判定,禁在其中再写前缀规则(契约 6)。两判据互补且不可互相替代:`meta_`/自造前缀由 `counter_id_legal` 拦,写点与读点拼错不一致由本条拦(现役 `feats.tres` 的 `:29`/`:39` 与 `:492`/`:501` 就是成对同名形态,改一半即中招) - [ ] `validate_trigger_row` 增分支:`do` 含 `counter_id` 时校验,非法→errs 追加 `{"category": "enum", ...}` 违例 - [ ] `_push_trigger` 增 assert:`do` 含 `counter_id` 时同规则 assert(树合成行路径,写错调试期致命;assert 消息以 `[效果引擎]` 前缀起头,供孤立验证扫描) -- [ ] 孤立验证(V9 assert 侧):`--headless --script` 最小驱动 rebuild 带「counter_id 带非法前缀」的合成行——输出扫到 `[效果引擎]` assert 签名=拦截在位(debug 通道;assert 不改退出码,判据=输出签名扫描) -- [ ] 新建 `game/tests/unit/data_config/counter_prefix_fatal_test.gd`:copy_tables 夹具→向 feats.tres 注入 `"counter_id": "meta_probe"` 行→`load_tables` 必须拒绝→quit(1);违规放行 quit(2)(reward_dangling_treasure_test.gd 同构,退出码协议同款) +- [ ] 孤立验证(V9 assert 侧):`--headless --script` 最小驱动**直调 `_push_trigger`** 塞一条 `"counter_id": "meta_probe"` 行——`rebuild` 只认固定规则键,坏前缀合成行无法经 `rebuild` 从外部注入,故注入点必须是 `_push_trigger`;输出扫到 `[效果引擎]` assert 签名=拦截在位(debug 通道;assert 不改退出码,判据=输出签名扫描) +- [ ] 新建 `game/tests/unit/data_config/counter_prefix_fatal_test.gd`:copy_tables 夹具两断言——①向 feats.tres 注入 `"counter_id": "meta_probe"` 行→`load_tables` 必须拒绝;②把某行 `when` 内 `fact: counter` 的读点 id 改成表内无声明的 `"pain_layer"`(比 `pain_layers` 少一个 s)→`load_tables` 必须拒绝。任一条违规放行即 quit(2)(reward_dangling_treasure_test.gd 同构,退出码协议同款) - [ ] `tests/run_all.gd` manifest 登记:`{"path": "res://tests/unit/data_config/counter_prefix_fatal_test.gd", "expect": 1, "negative": true}` ### T6 数据行与合成行改名(0.25d) **取用**:契约 7 的 4 枚新 id。**产出**:16 枚 id 全部合规(前缀即归属)。 -- [ ] `feats.tres`:`"twin_digs"`→`"adv_twin_digs"`(:29);`"instinct_atk"`→`"round_instinct_atk"`(:492);`pain_layers` 各行删 `"domain": "adventure"` 键(:375-377/:407 邻近/:533-535/:626-628——归 battle,N4);`twin_digs` 行删 domain 键、`insurance_used` 行删 `domain: battle` 键(:875-877);全部 `reset_at` 键删除(:209-212/:490-494/:514-518/:719-723) -- [ ] `effect_engine.gd` 合成行(:136-155):`tree_sense_sharp_used`→`lvl_tree_sense_sharp_used`、`tree_sense_guard_used`→`lvl_tree_sense_guard_used`(when id 与 counter_id 共六处字面:锋/守各 when 两行+do counter_id 一行);:116-122 注释内「domain=adventure」叙述同步改前缀口径 -- [ ] 全仓 grep 确认零 `domain`/`reset_at` 键残留于 feats.tres;`pain_layers`/`geo_types` 等 12 枚无前缀 id 零改名(无前缀=battle 即归属) +- [ ] `feats.tres`:**写点与读点成对改名**——`"twin_digs"`→`"adv_twin_digs"`(写 :29/读 `when.id` :39);`"instinct_atk"`→`"round_instinct_atk"`(写 :492/读 `value_counter` :501);`pain_layers` 各行删 `"domain": "adventure"` 键(:375-377/:407 邻近/:533-535/:626-628——归 battle,N4);`twin_digs` 行删 domain 键、`insurance_used` 行删 `domain: battle` 键(:875-877);全部 `reset_at` 键删除(:209-212/:490-494/:514-518/:719-723) +- [ ] `effect_engine.gd` 合成行(:136-155):`tree_sense_sharp_used`→`lvl_tree_sense_sharp_used`、`tree_sense_guard_used`→`lvl_tree_sense_guard_used`(when id 与 counter_id 共六处字面:锋/守各 when 两行+do counter_id 一行);**删除 :145/:155 两处 `"domain": "adventure"`**(随 DO_KEYS 删键,否则合成行自带出域键);:116-122 注释内「domain=adventure」叙述同步改前缀口径 +- [ ] `tree_rules_v11_test.gd` 夹具行(:33/:39)随合成行同源改 id + **删两处 `"domain": "adventure"`**——该夹具经 `validate_trigger_row` 校验,`DO_KEYS` 删键后不删此处即当场转红 +- [ ] 过期注释清扫(§3 清单逐处):`effect_engine.gd:42/:70-71/:118-120`、`grant_segment.gd:307`、`run_ledger.gd:7-8/:12`、`level_runner.gd:630` +- [ ] 全仓 grep 确认零 `domain`/`reset_at` 键残留(feats.tres+引擎合成行+测试夹具三处都算);`pain_layers`/`geo_types` 等 9 枚无前缀 id 零改名(前缀判据只禁 `meta_`,其余落 battle 即归属——判据理由与残余风险的承接面见 T5 与 §12 裁点②;14 枚去三枚已带 `round_` 前缀、再去本批改名的 `twin_digs`/`instinct_atk` 两枚,落地后无前缀者恰为 9 枚) -### T7 验收断言+旧测试迁移+变异验证+同种子复放比对(1–1.5d) +### T7 验收断言+旧测试迁移+变异验证+同种子复放比对(1.25–1.75d) -**取用**:T1–T6 全部产物;§9 验证闸清单(V1–V14 断言内容以本卡为唯一规格)。**产出**:V1–V13 全绿+变异验证记录表+G1 判读记录。 +**取用**:T1–T6 全部产物;§9 验证闸清单(V1–V14 断言内容以本卡为唯一规格)。**产出**:V1–V13 全绿+变异验证记录表+三组复放判读记录(承载提案 §7.10.12 的 G1 已知差异面条目)。 -- [ ] **新增单测断言**(套件内新增,断言尾缀〔无状态化 Vn〕):V2/V3/V7/V13 落 `feat_vouchers_test.gd`(V16 键名 `pain_layers:3, twin_digs:5`→`adv_twin_digs:5` 等活键改写;V25 全组保绿不改断言内容;新增 H1:bp_legacy 注入 `"tree_sense_sharp_used": 2` 旧键 resume 受理零崩溃);V9 落 `counter_prefix_fatal_test.gd`(T5) -- [ ] **新增冒烟断言段**(`smoke_all.gd` 树规则段近旁):V1(两编排器共享 RunLedger,第 1 战 `request_dig(0, false)` 一次无返还+桶值 1,第 2 战一次返还成立+桶值 2);V4/V5(两编排器经 enc["level_counters"] 共享同字典:第 1 战两次 `_fx.dispatch(counters_ctx, "mine_hit", {})` 命中桶值 2,第 2 战同 dispatch 返回空且桶值不动;新 LevelRunner 新桶为空);V6(第 1 战经 `_judge_seal` 置 `insurance_used=1`,第 2 战读 0);V8(round 桶直写非零→`orch._emit_round_start()`→全零,battle 前缀键不动) +- [ ] **新增单测断言**(套件内新增,断言尾缀〔无状态化 Vn〕):V2/V3/V7/V13 落 `feat_vouchers_test.gd`(V16 键名 `pain_layers:3, twin_digs:5`→`adv_twin_digs:5` 等活键改写;V25 全组保绿不改断言内容;新增 H1:bp_legacy 同时注入 `"tree_sense_sharp_used": 2` 与 `"pain_layers": 3` 两枚旧键,resume 受理零崩溃、旧键留桶成死键——`pain_layers` 旧键即契约 8 的续玩差异面);V9 落 `counter_prefix_fatal_test.gd`(T5 两断言) +- [ ] **新增冒烟断言段**(`smoke_all.gd` 树规则段近旁;每条夹具的 enc 键写死,不留给实现期自由发挥):V1(夹具=同一 `RunLedger` 下两次 `begin_battle`,**两 enc 均带 `"feats": ["twin_pick"]`**——不带则 `adv_twin_digs` 无订阅行,断言空转;第 1 战 `orch1.action_economy.request_dig(0, false)` 一次无返还+桶值 1,第 2 战一次返还成立+桶值 2);V4/V5(夹具=两编排器 enc 均带 `"tree_rules": ["sense_sharp", "sense_guard"]` 且 `"level_counters"` 传同一字典引用:第 1 战两次 `_fx.dispatch(counters_ctx, "mine_hit", {})` 命中桶值 2,第 2 战同 dispatch 返回空且桶值不动;新 LevelRunner 新桶为空);V6(第 1 战经 `_judge_seal` 置 `insurance_used=1`,第 2 战读 0);V8(round 桶直写非零→`orch._emit_round_start()`→全零,battle 前缀键不动) - [ ] **旧断言迁移/摘除**(F2——同批同轮):`effect_words_t1_test.gd` ⑥(:77-94 export/seed 往返)改桶语义断言(共享 adventure 桶字典往返)、⑦(:96-124 reset_at/spend)重写(round 桶轮始清空语义+静态 spend);`smoke_all.gd` `:6076-6083`(counter_add+export/seed 链)改共享桶形态、`:6124-6128`(`_reset_tree_limited_counters` 直呼)删除;`:1419-1602` 裸引擎段 53 处 dispatch+8 处写口改 ctx 形态(逐行扫尽,rig 顶自建 ctx 或取 `orch.counters_ctx`);`tree_rules_v11_test.gd:29-39` 字面随 T6 新 id;`settle_segments_test.gd:32-33` 样本 id `dig_combo`→`geo_types`+ctx 形态;`treasure_effects_test.gd:34/:45/:53-56` dispatch 加 ctx;各 rig enc `"adventure_counters": {}` 死键删除(编排器只读 `enc["ledger"]`,:372 实证) -- [ ] **静态扫描 S 段**(`static_scan.sh`):新增规则组——`counters_export`/`counters_seed`/`counters_merge_export`/`counters_seed_snapshot`/`_reset_tree_limited_counters` 零命中+带引号旧 id 字面 `"tree_sense_sharp_used"`/`"tree_sense_guard_used"`/`"twin_digs"`/`"instinct_atk"` 零命中(带引号匹配防新名误伤);`run_all_gates.sh` 域内已有 static_scan,无闸件清单改动 -- [ ] **变异验证**(§9 变异表 4 条逐条:注入→最窄闸见红→`git checkout -- <文件>` 还原→复跑回绿→记录) -- [ ] **同种子复放比对**(V12):先做**锚新鲜度核对**——用批前基线码(T0 记录的起点 commit)重放种子 81000–81001 两局,与现行锚 `sim-data/runsum_m3iter9exit_81000_n400_20261003.jsonl` 对应行逐位比对,一致方判锚可用(不一致=锚与 HEAD 玩法口径脱钩,L3 停机呈报,禁带病判读);核对通过后重放锚内 normal 档种子 81000–81019(20 局,零局新采集),按 §7.10.12 分组判读(未受影响局=feat_mode off 或装备集不含双管镐/sense 两组→全字段逐位一致;受影响局→输入面恒等+`levels_cleared` 分布不得上行);逐位差异明细记实现报告 +- [ ] **静态扫描 S 段**(`static_scan.sh` 新增 S11):规则=`counters_export`/`counters_seed`/`counters_merge_export`/`counters_seed_snapshot`/`_reset_tree_limited_counters` 零命中+带引号旧 id 字面 `"tree_sense_sharp_used"`/`"tree_sense_guard_used"`/`"twin_digs"`/`"instinct_atk"` 零命中(带引号匹配防新名误伤)。**扫描面必须自带扩面**:现役 `:20-24` 的扫描路径单点只有 `game/core` 与 `game/presentation`、`scan_files` 只数 `.gd`,而改名与旧字面同时存在于 `feats.tres`、`game/tests/`、`game/smoke/` 三处——本段单独声明扫 `game/**/*.gd` 与 `game/data/tables/*.tres`,并沿用 `require_scan_face` 同规做扫描面非空自检(空面判红,防静默空转);`run_all_gates.sh` 域内已有 static_scan,无闸件清单改动 +- [ ] **变异验证**(§9 变异表 7 行逐条:注入→最窄闸见红→`git checkout -- <文件>` 还原→复跑回绿→记录) +- [ ] **批内同种子复放比对**(V12):批后码按 T0 的同一命令行重跑三组 40 局(STATE=post,落 `sim-data/v12_post_*_.jsonl`),再用 `tools/parity_compare.py` 三组各判读一次——off 组 `--mode parity` 要求 20 局整条记录逐位相等;formed 组与 rules 组 `--mode input-parity` 要求输入面八字段(`policy`/`seed`/`atk_pct`/`hp_pct`/`route`/`attune`/`equipped`/`feat_mode`)与顶层字段集恒等、种子集与局数一致;输出面差异打差异表、`levels_cleared` 合计与直方图作报告行(formed 组预期不降、rules 组预期不升;10 局无统计功效,**方向不作判红依据**)。采集命令与分组(normal 档、route=min、attune/shop 显式 off,逐字与 T0 准备阶段一致): + + ```bash + mc () { "$GODOT" --headless --path "$(cygpath -m "$PWD/game")" \ + --script res://smoke/adventure_monte_carlo.gd -- \ + "$1" "$2" normal min off off "$3" "$4" 2>&1 | grep '^RUNSUM ' > "$5"; } + mc 20 81000 off "" sim-data/v12_post_off_n20.jsonl + mc 10 81000 formed "" sim-data/v12_post_formed_n10.jsonl + mc 10 81000 rules "sense_sharp,sense_guard" sim-data/v12_post_rules-sense_n10.jsonl + ``` + + 判红后的归因顺序(先排除环境再查码):在基线码上重放 5 局对哈希——一致=代码漂移(L3),不一致=环境漂移(console exe/导入缓存/种子面),按 process-conventions 环境自救清单处理后再判。逐位差异明细与三组判读结论记实现报告;40 局合计约 1.5 分钟(准备阶段实测 normal 档单局 1.8 秒),禁顺手加档 - [ ] 里程碑步出口:`tools/run_all_gates.sh --code`(代码域闸全绿);波内修复只做出红最小单元的最窄确认 ### T8 产出物落位卡(0.25d) **取用**:T0–T7 全部记录。**产出**:`reports/` 三份齐+06 状态就绪。 -- [ ] 实现报告 `reports/iter-实现报告-<日期>.md`:各 T 卡状态+变异验证记录表(注入点 file:line/跑的闸/红输出摘要/还原结论)+G1 判读记录+实机目检总清单(V14 登记) +- [ ] 实现报告 `reports/iter-实现报告-<日期>.md`:各 T 卡状态+变异验证记录表(注入点 file:line/跑的闸/红输出摘要/还原结论)+三组复放判读记录(基线与复放六个文件的 sha256、T0 首提交 SHA、逐位差异明细、`levels_cleared` 直方图)+实机目检总清单(V14 登记) - [ ] 代拍板追认单 `reports/iter-代拍板-<日期>.md`(§11 白名单内微决策逐条备案) -- [ ] 反哺点清单 `reports/iter-反哺点-<日期>.md`:§6 同步面五条逐条落点(architecture.md 三处改写文案与依据、tests/README 套件数、07 目检入册项) +- [ ] 反哺点清单 `reports/iter-反哺点-<日期>.md`:§6 同步面逐条落点(architecture.md 三处改写文案与依据、tests/README 套件数、07 目检入册项、**提案三处口径订正(§7.10.3/§7.10.12/§7.7,依 §12 裁决以本卡为准)**、`sim-data/README.md` 批次例外登记) - [ ] 轻闸全绿后合并前自查:`game/` 与 `tools/` 改动全在案、`design/` 与根规则文件零触碰(`git diff --stat` 核对) ## 9. 验证闸(逐需求点验收清单) -**闸口径**:批末=代码域闸全绿(冒烟+单元+探针+渲染/静态,`tools/run_all_gates.sh --code`)+同种子复放比对(V12,零局新采集)。里程碑步(波/T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试/工具先行孤立验证再并入全套。本批无数值改动,改前改后读数对比由 V12 分组判读承载。 +**闸口径**:批末=代码域闸全绿(冒烟+单元+探针+渲染/静态,`tools/run_all_gates.sh --code`)+批内同种子复放比对(V12,批后 40 局,二档上限内)。里程碑步(波/T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试/工具先行孤立验证再并入全套。本批无数值改动,三处预期行为差异(契约 1)由 V12 三组判读与 V1/V4/V5 确定性断言共同承载——方向性结论只由后者下,V12 只负责「没改坏」。 **逐需求点清单**(断言尾缀〔无状态化 Vn〕;「测什么/怎么测/谁验」三问逐条可答): | # | 需求点 | 测什么 | 怎么测(注入粒度) | 落点 | 谁验 | |---|---|---|---|---|---| -| V1 | adventure 桶跨战持久(`run_ledger.gd:42` 缺陷消解回归钉面) | 第 1 战写入第 2 战可读、读写走真实事件面 | 两编排器共享 `RunLedger`:第 1 战 `orch1.action_economy.request_dig(0, false)`(无返还,`adv_twin_digs`=1)→第 2 战(同 ledger)一次挖返还成立+桶值 2 | 冒烟新段 | 自动 | +| V1 | adventure 桶跨战持久(`run_ledger.gd:42` 缺陷消解回归钉面) | 第 1 战写入第 2 战可读、读写走真实事件面 | 夹具=同一 `RunLedger` 下两次 `begin_battle`、两 enc 均带 `"feats": ["twin_pick"]`:第 1 战 `orch1.action_economy.request_dig(0, false)`(无返还,`adv_twin_digs`=1)→第 2 战一次挖返还成立+桶值 2 | 冒烟新段 | 自动 | | V2 | adventure 桶新冒险置空 | `start_adventure` 后桶空 | `start_adventure(301,...)` 后 `run_ledger.adventure_counters` 为空 | `feat_vouchers_test.gd` | 自动 | | V3 | adventure 桶随断点往返 | 快照/回填逐位相等 | 写桶→`_on_level_finished`→`breakpoint_snapshot`→`resume_adventure`→逐键比对(键随新 id) | `feat_vouchers_test.gd`(V16 改写) | 自动 | | V4 | level 桶同关跨战保持、进关清零 | 共享桶第 2 战保值;新 LevelRunner 新桶空 | 两编排器 enc["level_counters"] 同引用:第 2 战读 `lvl_tree_sense_*` 保持;再 new LevelRunner 断言 `level_counters` 空 | 冒烟新段 | 自动 | -| V5 | tree_sense 每关限 2 次(削弱正面确认) | 第 1 战用满→第 2 战 lt 2 闸关零命中 | V4 同款共享桶:第 1 战两次 dispatch mine_hit 命中(桶值 2)→第 2 战同 dispatch 返回空且桶值不动 | 冒烟新段 | 自动 | +| V5 | tree_sense 每关限 2 次(削弱正面确认) | 第 1 战用满→第 2 战 lt 2 闸关零命中 | 夹具=V4 同款共享 `level_counters` 引用、两 enc 均带 `"tree_rules": ["sense_sharp", "sense_guard"]`:第 1 战两次 dispatch mine_hit 命中(桶值 2)→第 2 战同 dispatch 返回空且桶值不动 | 冒烟新段 | 自动 | | V6 | battle 桶随宿主销毁 | 第 2 战读 `insurance_used`==0 | 第 1 战 `_judge_seal` 置 1→新编排器 begin_battle 后读 0 | 冒烟新段 | 自动 | | V7 | 完美保险每战限次一次(卡② V25 迁移保绿) | V25 全组断言原样绿 | 沿用 V25 注入口径零改写——双账同点双记不改面(契约 5) | `feat_vouchers_test.gd:130-188` | 自动 | | V8 | round 桶轮始清空 | 轮始后 round 桶全零、他桶不动 | round 桶直写非零→`orch._emit_round_start()`→全零;`fx_counters_battle` 内键不动 | 冒烟新段 | 自动 | -| V9 | counter_id 非法前缀加载致命(.tres 行+树合成行双落点) | 坏前缀行 load_tables 拒绝;合成行 assert 触发有据 | 夹具注入 `"counter_id": "meta_probe"`→load_tables false→expect 1;assert 侧=T5 孤立验证(最小驱动 rebuild 坏前缀合成行,输出扫 `[效果引擎]` assert 签名)+变异表第 4 行证明拦截 | `counter_prefix_fatal_test.gd`(expect 1, negative)+T5 孤立验证 | 自动 | -| V10 | 旧件零残留 | 五符号+四带引号旧 id 字面全仓零命中 | static_scan 新 S 段(规则见 T7) | `static_scan.sh` | 自动 | +| V9 | counter_id 非法前缀加载致命(.tres 行+树合成行双落点)+读点无声明加载致命(引用闭合) | 坏前缀行 load_tables 拒绝;合成行 assert 触发有据;读点 id 不在声明集 load_tables 拒绝 | 夹具①注入 `"counter_id": "meta_probe"`→load_tables false;夹具②把某 `when` 读点 id 改成 `"pain_layer"`(无声明)→load_tables false;assert 侧=T5 孤立验证(**直调 `_push_trigger`** 塞坏前缀行,输出扫 `[效果引擎]` assert 签名——`rebuild` 不认外部键,经它注入不可执行)+变异表第 4/5 行证明拦截 | `counter_prefix_fatal_test.gd`(expect 1, negative)+T5 孤立验证 | 自动 | +| V10 | 旧件零残留 | 五符号+四带引号旧 id 字面在 `game/**/*.gd` 与 `game/data/tables/*.tres` 零命中(面含测试与 smoke,不只 core) | static_scan 新增 S11 段(扫描面自带扩面+非空自检,规则见 T7) | `static_scan.sh` | 自动 | | V11 | 旧断言同批摘除 | 冒烟/单测无旧件断言残留 | V10 扫描面覆盖测试文件+F2 清单逐项核对(`effect_words_t1` ⑥⑦/`smoke :6076-6083`/`:6124-6128`/`:1419-1602`) | 冒烟+单测迁移轮 | 自动+实现报告核对表 | -| V12 | 同种子复放分组判读 | 锚新鲜度核对通过后:未受影响局逐位一致;受影响局输入面恒等+`levels_cleared` 不上行 | 批前基线码先重放 81000–81001 两局与现行锚 `runsum_m3iter9exit_81000_n400_20261003.jsonl` 逐位比对(新鲜度闸);通过后批后码重放锚内 normal 档 81000–81019(20 局);分组判读按提案 §7.10.12 | 复放脚本+实现报告判读记录 | 自动+人工判读 | -| V13 | 旧档断点加载不崩 | 旧键 resume 受理零崩溃 | bp_legacy 注入 `"tree_sense_sharp_used": 2`→`resume_adventure` 受理、旧键留桶 | `feat_vouchers_test.gd`(V16 同构) | 自动 | +| V12 | 批内同种子复放三组判读 | off 组整条记录逐位相等;formed 组/rules 组输入面八字段与顶层字段集恒等、种子集与局数一致、零崩溃;输出面差异与 `levels_cleared` 方向只记报告 | T0 留盘基线(三组 40 局,哈希在册)vs 批后同命令同种子复放 40 局;`tools/parity_compare.py` 三组各跑一次(判据与命令见 T7) | 复放比对器+实现报告判读记录 | 自动+人工判读 | +| V13 | 旧档断点加载不崩 | 旧键 resume 受理零崩溃 | bp_legacy 同时注入 `"tree_sense_sharp_used": 2` 与 `"pain_layers": 3`→`resume_adventure` 受理、旧键留桶成死键 | `feat_vouchers_test.gd`(V16 同构) | 自动 | | V14 | 天赋树锋/守削弱玩家可感知(登记不阻塞) | 每关第 3 次起无减免/无返还 | 用户实战目检:同关第 3 次踩雷不再减半、第 3 次标错不再返 AP | 实机目检总清单+07 入册(反哺点) | 用户目检 | **变异验证必做**(无变异红记录只写「已实现,拦截能力未证」): @@ -253,15 +284,17 @@ | V5 | V4/V5 两编排器改传各自新建 level 字典(复刻 :838-841 旧形态跨战不共享) | 跑 `smoke_all.gd` 单脚本,核对 V5 断言红 | V5 红 | | V9(.tres 侧) | 注释 `validate_trigger_row` 前缀校验分支 | `counter_prefix_fatal_test.gd` 单跑 | 套件转「违规放行」态判红 | | V9(合成行侧) | 注释 `_push_trigger` 内前缀 assert 行 | T5 孤立验证驱动单跑(输出签名扫描) | assert 签名消失=拦截失效判红 | -| V10 | 任一源文件临时写回一处 `"counters_export"` 引用 | `static_scan.sh` 单跑该 S 段 | 扫描红 | +| V9(引用闭合侧) | 注释 `config_db_cross_validator.gd` 的闭合校验调用行 | `counter_prefix_fatal_test.gd` 单跑 | 夹具②(读点无声明)违规放行=拦截失效判红 | +| V10 | 任一源文件临时写回一处 `"counters_export"` 引用 | `static_scan.sh` 单跑 S11 段 | 扫描红 | +| V12(采集器侧) | 还原 T0 首提交那一行(`Array(…)` 包裹去掉) | T7 复放 rules 组判读 | rules 组与 off 组逐位相同=分组空转,被 L3「采集器补丁缺位」条款捕获 | **测试方式两分法**:V1–V13 全部=调试接口直改/直调核心层(共享字典注入、`request_dig`/`_judge_seal`/`_emit_round_start` 核心写口直调),不经 UI;V14=用户目检(登记不阻塞,验收时间用户自定)。 ## 10. 异常分级 - **L1 自救**:编译错/笔误级红;孤立验证失败(新类/新函数首跑);复放脚本参数错重跑。 -- **L2 记录继续**:V12 受影响局保守超集判定边界个案(某局归类存疑)——按受影响组从严判读并记录;负面套件在 release 模式 assert 剥离致假绿——换 debug 通道验证并记录(配置问题非代码缺陷)。 -- **L3 停机呈报**:V12 未受影响局出现任何逐位差异(确定性破约);V7/V25 任何一条红(契约 5 破);V13 崩溃;`pain_layers` 行为漂移(契约 8 破);写口语义与现役不一致导致 V1–V8 连带红且无法归因单点。 +- **L2 记录继续**:V12 的 formed/rules 两组输出面差异面过大(半数以上字段位移)——属轮数一变后的 RNG 级联放大,如实记录不判红;负面套件在 release 模式 assert 剥离致假绿——换 debug 通道验证并记录(配置问题非代码缺陷)。 +- **L3 停机呈报**:V12 的 off 组出现任何逐位差异,或 formed/rules 两组输入面八字段/字段集/种子集/局数任一不一致(确定性破约);rules 组复放结果与 off 组逐位相同(采集器补丁缺位,分组空转、数据不可信);V7/V25 任何一条红(契约 5 破);V13 崩溃;`pain_layers` 单战「攒层→附加→清零」行为漂移(契约 8 破);写口语义与现役不一致导致 V1–V8 连带红且无法归因单点。 - 环境故障(worktree 缓存/资源导入/console exe)按 process-conventions 异常分级自救清单处理。 ## 11. 代拍板白名单(超清单必呈报) @@ -272,6 +305,8 @@ 4. `feats.tres` 行内键序调整(键集与值已锁)。 5. `effect_engine.gd` 合成行注释的措辞更新(口径已锁:前缀表述)。 6. 负面套件内诊断文案措辞(退出码协议已锁)。 +7. `tools/parity_compare.py` 的内部实现与输出排版(两判据模式、`--expect`、退出码 0/1/2 与「字段集从基线推导」四条已锁)。 +8. 复放文件名里的码态后缀取值与差异表行数(三组名、种子面、留盘位置已锁)。 ## 12. 待裁点 @@ -279,14 +314,25 @@ 本卡全部设计定值承自提案 §7(N1–N6)、§7.7(零采集)、§7.10(缺口闭合),均为「已生效裁定+硬纪律」推导所得并写明依据;其中以下各项带「可否决」标注(提案 §7.9/§7.10.14 同口径),用户审卡时可单独推翻、推翻即回改卡:§7.9 五条(立项判据载体/domain+reset_at 删键/`adventure_counters` 容器名不改/旧档不迁移/两编译名单删除)与 B6(dig_combo 死路删除)。卡片成立还需 grilling 复核通过(零待裁点+验收三问逐条可答已自查,见下)。 +**owner 已裁六项(对抗复核轮 2026-10-20,已并入正文对应节,非待裁点)**: + +| # | 裁决 | 落点 | 判据 | +|---|---|---|---| +| ① | 复放基线改批内重采(三组 40 局,二档上限内),`sim-data/` 纪律③⑦开批次例外 | §1.6/契约 10/T0/T7/V12 | 现行锚 24 字段面与现采 33 字段面不同构、无 `feat_mode` 分组面,且 `sim-data/` 不入 git 致批 worktree 内根本没有该文件——「锚新鲜度核对」一步必红,原方案不可执行 | +| ② | 前缀判据采「只禁 `meta_`+其余落 battle」的松版,另加装载期引用闭合校验 | §1.5/契约 6/T5/V9 | `feats.tres` 现有 14 枚 id 全含下划线、首段除三枚 `round_` 外全是普通词,严版误伤全部既有 battle id;封闭前缀词表=第二事实源(2026-10-19 registry 注销裁定同类);实测风险形态是写读成对字面改一半,闭合校验正面拦截 | +| ③ | 改名与删键面扩到读点、合成行、测试夹具与过期注释 | T6/§7 文件结构 | `:39`/`:501` 读点、`effect_engine.gd:145/:155` 与 `tree_rules_v11_test.gd:33/:39` 的 `domain` 残留、七处注释——原卡遗漏,其中夹具残留会当场转红 | +| ④ | `pain_layers` 措辞改为「单战零变更+旧档续玩不再跨战」,列第三处预期差异 | 契约 1/8/V13 | 断点回灌路径(`adventure_runner.gd:206-208`→`:1033`)使旧档续玩可跨战携带该键,改后不再携带——属缺陷消解,不得写成「零语义变化」 | +| ⑤ | 验收夹具写死到 enc 键字面;V9 assert 侧注入点改直调 `_push_trigger` | §9 V1/V5/V9/T7 | `rebuild` 只认固定规则键,经它注入坏前缀合成行不可执行;V1/V5 不带 `"feats"`/`"tree_rules"` 则订阅行为空、断言空转 | +| ⑥ | 采集器 `rules` 注入类型缺陷修复入本批(T0 首提交),不单独开非迭代批 | T0/§7 文件结构/V12 | 一行测试工具修复在本批末的代码域闸里一起验,省一次全量闸;不修则 rules 组恒假绿,V12 削弱面失去复放承载 | + --- ## 附:任务卡自审五查记录(2026-10-20 成文自检) -**grilling 复核轮**:成文后经独立会话对抗复核(新会话视角、不带写卡人假设),五项回炉点已全落——①行号群订正(成员块 :83-88/:84-87、`counters_seed` :255、`EffectEngine.new` :271、合成行 :136-155、注释 :137、rebuild :1610、裸引擎段实数 53 处、合成行字面六处);②V12 具名锚+T7 增锚新鲜度核对步(批前基线码两局配对在先);③V9 assert 侧补孤立验证与变异行;④T5 判定函数名落定 `counter_id_legal`;⑤估时头对齐 T 表加总+超盒切分预案。复核结论「定点回炉后可交用户审」已执行。 +**grilling 复核轮**:成文后经独立会话对抗复核(新会话视角、不带写卡人假设),五项回炉点已全落——①行号群订正(成员块 :83-88/:84-87、`counters_seed` :255、`EffectEngine.new` :271、合成行 :136-155、注释 :137、rebuild :1610、裸引擎段实数 53 处、合成行字面六处);②V12 复放基线的取数面与判据(现落定为批内三组 40 局,见 §12 裁点①);③V9 assert 侧补孤立验证与变异行;④T5 判定函数名落定 `counter_id_legal`;⑤估时头对齐 T 表加总+超盒切分预案。复核结论「定点回炉后可交用户审」已执行。 1. **规格覆盖**:完成定义 1–8 ↔ T 卡映射——1→T2;2→T1;3→T2/T3;4→T1;5→T5;6→T7(V12);7→T3;8→T7(V13)。验收 V1–V14 逐条有落点。✓ 2. **步骤扫描**:各步一动作一核查结果;实现体未写(签名+断言已锁);无「TBD/酌情」句式。✓ 3. **类型一致性**:`EffectContext` 字段名、编排器/LevelRunner 成员名、enc 键名、静态函数签名在 T1/T2/T3/T7 引用处逐字一致(契约 7 锁定)。✓ -4. **审查焦点**:规格暗示的失败模式对照——确定性漂移(V12 未受影响组+锚新鲜度闸)、引用切断(契约 3+V1 变异)、限次失效回退(V5 变异)、加载致命旁路(V9 双侧变异)、死路复活(V10)——均有承载;「同轮 dispatch 内 round 桶清空与订阅行命中并存」的时序语义由 V8+现役特判位置保持承载。✓ +4. **审查焦点**:规格暗示的失败模式对照——确定性漂移(V12 off 组逐位判据+判红先归因环境再归因码)、引用切断(契约 3+V1 变异)、限次失效回退(V5 变异)、加载致命旁路(V9 三侧变异:`.tres`/合成行/引用闭合)、死路复活(V10)、复放分组空转(rules 组与 off 组同形即 L3,配采集器侧变异行)——均有承载;「同轮 dispatch 内 round 桶清空与订阅行命中并存」的时序语义由 V8+现役特判位置保持承载。✓ 5. **篇幅比例**:本卡以签名/断言/落点为主,无函数体代码块。✓ From 0b95a0c33396f2bf1e1a4238bbe4874d4d89e8f5 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 19:22:14 +0800 Subject: [PATCH 19/59] =?UTF-8?q?docs(=E4=BB=A3=E7=A0=81=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E8=AF=8D=E6=B8=85=E6=89=AB=E6=89=B9=C2=B7?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E6=95=B4=E6=94=B9):=20=E5=8D=A1=E2=91=A0?= =?UTF-8?q?=E4=BB=8E=20design/research/=20=E7=A7=BB=E5=85=A5=20reports/?= =?UTF-8?q?=EF=BC=88=E9=9C=80=E6=B1=82=E5=8D=A1=E7=89=87=E5=94=AF=E4=B8=80?= =?UTF-8?q?=E5=AE=B9=E5=99=A8=E8=A7=84=E7=BA=A6=EF=BC=89=E2=80=94=E2=80=94?= =?UTF-8?q?06=20=E7=8A=B6=E6=80=81=E8=A1=8C=E4=B8=8E=20roadmap=20=E8=BF=AD?= =?UTF-8?q?=E4=BB=A3=2032=20=E8=A1=8C=E5=8D=A1=E7=89=87=E5=88=97=E4=B8=A4?= =?UTF-8?q?=E5=A4=84=E8=B7=AF=E5=BE=84=E5=90=8C=E6=89=B9=E6=94=B9=E6=8C=87?= =?UTF-8?q?=EF=BC=8C=E6=B5=81=E6=B0=B4=E7=BA=BF=E9=97=B8=E4=B8=A4=E7=BA=A2?= =?UTF-8?q?=EF=BC=88=E5=87=AD=E6=8D=AE=E7=BC=BA=E5=A4=B1=EF=BC=8F=E5=B7=B2?= =?UTF-8?q?=E7=BC=96=E8=BF=AD=E4=BB=A3=E6=97=A0=E5=8F=AF=E5=BC=95=E5=8D=A1?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=EF=BC=89=E6=B6=88=E8=A7=A3=EF=BC=8C=E7=8E=B0?= =?UTF-8?q?=20PASS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/gdd/06-待办清单.md | 2 +- .../需求卡片-代码注释禁用词清扫批-2026-10-20.md | 0 roadmap.md | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename {design/research => reports}/需求卡片-代码注释禁用词清扫批-2026-10-20.md (100%) diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index 1da08f7c..e5863107 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -687,7 +687,7 @@ **归属**:game/ 代码与数据表(代码域,走独立 worktree 批;并行避让——`changelog-retire-20261019` 在盘未合回且正在改 `AGENTS.md` 与 `design/dev/code-conventions.md`,本批禁碰这两个文件,S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`) -**状态**:已写卡(design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md,**v1.3**)+已编迭代 32 +**状态**:已写卡(reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md,**v1.3**)+已编迭代 32 --- diff --git a/design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md b/reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md similarity index 100% rename from design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md rename to reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md diff --git a/roadmap.md b/roadmap.md index ee3bcfcb..b2dff6d5 100644 --- a/roadmap.md +++ b/roadmap.md @@ -65,7 +65,7 @@ | 迭代 29 | 已完成(2026-10-16) | 已退役(git 历史可考) | 2026-10-16 | — | 已退役(git 历史可考) | | 迭代 30 | 已完成(2026-10-17) | 已退役(git 历史可考) | 2026-10-16 | — | 已退役(git 历史可考) | | 迭代 31 | 已完成(2026-10-19) | 已退役(git 历史可考) | 2026-10-18 | ≈1.5 周 | 已退役(git 历史可考) | -| 迭代 32 | 待开工 | design/research/需求卡片-代码注释禁用词清扫批-2026-10-20.md | 2026-10-20 | ≈0.5 周 | — | +| 迭代 32 | 待开工 | reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md | 2026-10-20 | ≈0.5 周 | — | - 历史行的「—」= 该列事实不可考:迭代 1~8 早于需求卡片制;编排时点与预计周期不再回溯,细节查 git 提交史。 - 「已退役(git 历史可考)」= 需求卡片或实现报告曾存在,已按「证据只留最新」退役;已完成迭代的实现报告列只填 reports/ 现存路径或本保留字,不填「—」。 From 44e5743d8a867ee840ca922d7b71c7d04ac6e257 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 19:23:20 +0800 Subject: [PATCH 20/59] =?UTF-8?q?fix(06=20=E6=AD=BB=E9=93=BE):=20=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=B3=A8=E9=87=8A=E7=A6=81=E7=94=A8=E8=AF=8D=E6=B8=85?= =?UTF-8?q?=E6=89=AB=E6=89=B9=E6=9D=A1=E7=9B=AE=E5=BD=92=E5=B1=9E=E8=A1=8C?= =?UTF-8?q?=E7=9A=84=E6=97=A7=E7=9B=AE=E5=BD=95=E8=B7=AF=E5=BE=84=20design?= =?UTF-8?q?/dev/=20=E2=86=92=20design/engineering/=EF=BC=8807=20doc=5Flink?= =?UTF-8?q?=20=E4=B8=A5=E6=A0=BC=E6=A1=A3=E6=AD=BB=E9=93=BE=E5=BD=92?= =?UTF-8?q?=E9=9B=B6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/gdd/06-待办清单.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index e5863107..7b2f8573 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -685,7 +685,7 @@ **不做(待用户另裁)**:术语表 A 表词一族、doc-conventions 第 4 节流程动词一族、简明技术中文(STC)通用禁用词一族——三族的逐词计数与清单见卡片 §4「不做」表(本行不复制词面:06 正文引述禁词会自指引爆 doc_term 补充通道,判红)。 -**归属**:game/ 代码与数据表(代码域,走独立 worktree 批;并行避让——`changelog-retire-20261019` 在盘未合回且正在改 `AGENTS.md` 与 `design/dev/code-conventions.md`,本批禁碰这两个文件,S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`) +**归属**:game/ 代码与数据表(代码域,走独立 worktree 批;并行避让——`changelog-retire-20261019` 在盘未合回且正在改 `AGENTS.md` 与 `design/engineering/code-conventions.md`,本批禁碰这两个文件,S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`) **状态**:已写卡(reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md,**v1.3**)+已编迭代 32 From bd0ad0e44164df46db54bcfb7be0fa2a65f97962 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 19:25:09 +0800 Subject: [PATCH 21/59] =?UTF-8?q?docs(=E8=BF=AD=E4=BB=A3=2032=20=E7=BC=96?= =?UTF-8?q?=E6=8E=92):=20=E6=95=88=E6=9E=9C=E5=BC=95=E6=93=8E=E6=97=A0?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=8C=96=E6=89=B9=E7=BC=96=E5=85=A5=E8=BF=AD?= =?UTF-8?q?=E4=BB=A3=2032=E2=80=94=E2=80=94roadmap=20=E8=A1=8C=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E5=88=97=E8=BF=BD=E5=8A=A0=E4=B8=BA=E7=AC=AC=E4=BA=8C?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E5=BA=8F=E3=80=81=E9=A2=84=E8=AE=A1=E5=91=A8?= =?UTF-8?q?=E6=9C=9F=20=E2=89=880.5=20=E5=91=A8=E6=94=B9=20=E2=89=881.75?= =?UTF-8?q?=20=E5=91=A8=E3=80=81=E5=BD=93=E5=89=8D=E4=BD=8D=E8=BF=AD?= =?UTF-8?q?=E4=BB=A3=E4=BD=8D=E5=90=8C=E6=AD=A5=E4=B8=A4=E5=8D=A1=EF=BC=9B?= =?UTF-8?q?06=20=E6=9D=A1=E7=9B=AE=E7=8A=B6=E6=80=81=E6=9C=AB=E5=B0=BE?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E3=80=8C=E5=B7=B2=E7=BC=96=E8=BF=AD=E4=BB=A3?= =?UTF-8?q?=2032=E3=80=8D=EF=BC=88=E7=B4=AF=E7=A7=AF=E6=AE=B5=E4=BF=9D?= =?UTF-8?q?=E7=95=99=EF=BC=89=EF=BC=9B=E5=8D=A1=E7=89=87=E3=80=8C=E4=B8=8D?= =?UTF-8?q?=E5=81=9A=E3=80=8D=E8=A1=A8=E8=A1=A5=E4=B8=A4=E8=A1=8C=EF=BC=9A?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E4=BD=8D=E5=BD=92=E7=BC=96=E6=8E=92=E6=AE=B5?= =?UTF-8?q?=E7=BB=B4=E6=8A=A4=E3=80=81=E4=B8=8E=E5=8D=A1=E2=91=A0=E7=A6=81?= =?UTF-8?q?=E5=B9=B6=E8=A1=8C=E5=BC=80=E5=B7=A5=EF=BC=88=E5=90=8C=E6=94=B9?= =?UTF-8?q?=E4=B8=89=E6=96=87=E4=BB=B6=E6=B3=A8=E9=87=8A=E9=9D=A2=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/gdd/06-待办清单.md | 2 +- reports/需求卡片-效果引擎无状态化批-2026-10-20.md | 3 ++- roadmap.md | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index 7b2f8573..d2201e80 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -635,7 +635,7 @@ **归属**:architecture.md 与 game/core/effect_engine.gd(待立独立批) -**状态**:待裁决(是否统一寿命域口径——2026-10-19 已裁:统一口径方案作废,改走无状态化重构)+文档设计已闭合(design/research/提案-效果引擎无状态化-2026-10-19.md v1.2——2026-10-20 §7.10 闭合)+待写卡+已写卡(reports/需求卡片-效果引擎无状态化批-2026-10-20.md) +**状态**:待裁决(是否统一寿命域口径——2026-10-19 已裁:统一口径方案作废,改走无状态化重构)+文档设计已闭合(design/research/提案-效果引擎无状态化-2026-10-19.md v1.2——2026-10-20 §7.10 闭合)+待写卡+已写卡(reports/需求卡片-效果引擎无状态化批-2026-10-20.md)+已编迭代 32 --- diff --git a/reports/需求卡片-效果引擎无状态化批-2026-10-20.md b/reports/需求卡片-效果引擎无状态化批-2026-10-20.md index 8d6449ac..6dc28de1 100644 --- a/reports/需求卡片-效果引擎无状态化批-2026-10-20.md +++ b/reports/需求卡片-效果引擎无状态化批-2026-10-20.md @@ -91,7 +91,8 @@ | 编排器 5 个效果运行态(`_fx_ac_round`/`_fx_ac_battle`/`_fx_new_resource_types`/`_fx_bonus_delta`/`_perfect_forgiven`) | N6 定值:只归计数器,留编排器 | | 天赋树锋/守重新定价 | 独立议题,不进本批(§4.5 B3) | | architecture.md「系统无状态」原则补条 | 已登记 06 新条目(文档轨·待文档设计),归文档批;本批反哺点带依据 | -| `roadmap.md` 当前位 stale | 已呈报在案,归并行会话 | +| `roadmap.md`「当前位」三行 | 实现批不动——该节由编排段与批末登记维护(本卡编入迭代 32 时已由编排段同步) | +| 与同迭代卡①(代码注释禁用词清扫批)并行开工 | 禁并行:两批都改写 `effect_engine.gd`/`grant_segment.gd`/`run_ledger.gd` 等文件的注释面,本批开工须排在卡①合回之后(roadmap 迭代 32 行执行序①→②) | | MC 采集(V12 复放之外的任何档) | §7.7 定值:零数值改动=零采集——本批只跑 V12 的三组 40 局基线(已采完)与 40 局复放,不开任何读数档、不动现行锚与读数文件 | | 元素类型精化(`Dictionary[String, int]`) | S9 现行口径 `Dictionary[Variant, Variant]` 合格,精化另走裁决 | diff --git a/roadmap.md b/roadmap.md index b2dff6d5..29e6bd76 100644 --- a/roadmap.md +++ b/roadmap.md @@ -5,7 +5,7 @@ ## 当前位(只回答「现在该做什么」;三行内随批次换代,禁止在此扩写成状态快照) - **阶段**:M3——Alpha 版本的完整实现(2026-10-09 立规:未明令宣布完成前停留 M3,迭代只排 M3 需求,M4 不排期;根目录 stage.txt 为旧阶段开关仅存档)。 -- **迭代位**:迭代 1–31 全部已完成或已终止;**迭代 32 待开工**(卡①代码注释禁用词清扫批,2026-10-20 编入)。 +- **迭代位**:迭代 1–31 全部已完成或已终止;**迭代 32 待开工**(卡①代码注释禁用词清扫批+卡②效果引擎无状态化批,2026-10-20 编入,执行序①→②)。 - **下一步**:迭代 32 开工令(U0)归用户发。其余候选在 06 状态列——营地交互重做五卡(已写卡待编迭代)、冒险前资源配比预设(备选)、迭代 30 原卡②③(待美术/设计定稿后重新立卡)、玩家面残留禁字清扫(待写卡)。 ## 里程碑时间线 @@ -65,7 +65,7 @@ | 迭代 29 | 已完成(2026-10-16) | 已退役(git 历史可考) | 2026-10-16 | — | 已退役(git 历史可考) | | 迭代 30 | 已完成(2026-10-17) | 已退役(git 历史可考) | 2026-10-16 | — | 已退役(git 历史可考) | | 迭代 31 | 已完成(2026-10-19) | 已退役(git 历史可考) | 2026-10-18 | ≈1.5 周 | 已退役(git 历史可考) | -| 迭代 32 | 待开工 | reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md | 2026-10-20 | ≈0.5 周 | — | +| 迭代 32 | 待开工 | reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md、reports/需求卡片-效果引擎无状态化批-2026-10-20.md | 2026-10-20 | ≈1.75 周 | — | - 历史行的「—」= 该列事实不可考:迭代 1~8 早于需求卡片制;编排时点与预计周期不再回溯,细节查 git 提交史。 - 「已退役(git 历史可考)」= 需求卡片或实现报告曾存在,已按「证据只留最新」退役;已完成迭代的实现报告列只填 reports/ 现存路径或本保留字,不填「—」。 From f230bde1c373c932738e5e084aaeb7a245260bc9 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 20:02:20 +0800 Subject: [PATCH 22/59] =?UTF-8?q?docs(=E5=8D=A1=E2=91=A0=E5=A4=B1=E6=95=88?= =?UTF-8?q?=E9=81=BF=E8=AE=A9=E9=99=88=E8=BF=B0=E6=B8=85=E8=B4=A6):=2006?= =?UTF-8?q?=20=E5=BD=92=E5=B1=9E=E6=AE=B5=E4=B8=8E=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E4=B8=89=E5=A4=84=EF=BC=88=E5=A5=91=E7=BA=A6=2010=EF=BC=8F?= =?UTF-8?q?=E4=B8=8D=E5=81=9A=E8=A1=A8=E8=A1=8C=EF=BC=8F=E5=81=9C=E6=9C=BA?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=205=EF=BC=89=E5=88=A0=E5=8E=BB=E3=80=8Cchang?= =?UTF-8?q?elog-retire-20261019=20=E5=9C=A8=E7=9B=98=E6=9C=AA=E5=90=88?= =?UTF-8?q?=E5=9B=9E=E3=80=8D=E9=81=BF=E8=AE=A9=E5=89=8D=E6=8F=90=EF=BC=88?= =?UTF-8?q?=E8=AF=A5=E6=89=B9=E5=B7=B2=E4=BA=8E=20c5200b6b=20=E5=85=A5=20m?= =?UTF-8?q?aster=EF=BC=8C=E5=89=8D=E6=8F=90=E5=A4=B1=E6=95=88=EF=BC=89?= =?UTF-8?q?=EF=BC=8C=E7=BA=A6=E6=9D=9F=E6=9C=AC=E4=BD=93=E4=BF=9D=E7=95=99?= =?UTF-8?q?=E5=B9=B6=E6=94=B9=E6=8C=82=E6=B5=81=E6=B0=B4=E7=BA=BF=E7=BA=A2?= =?UTF-8?q?=E7=BA=BF=E4=BE=9D=E6=8D=AE=EF=BC=88=E8=BF=AD=E4=BB=A3=E6=89=B9?= =?UTF-8?q?=E7=A6=81=E5=86=99=20design/=20=E4=B8=8E=E6=A0=B9=E8=A7=84?= =?UTF-8?q?=E5=88=99=E6=96=87=E4=BB=B6=EF=BC=89=EF=BC=9B=E9=A1=BA=E5=B8=A6?= =?UTF-8?q?=E6=8A=8A=E6=97=A7=E7=9B=AE=E5=BD=95=20design/dev/=20=E4=B8=89?= =?UTF-8?q?=E5=A4=84=E5=86=99=E6=B3=95=E6=94=B9=E4=B8=BA=20design/engineer?= =?UTF-8?q?ing/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/gdd/06-待办清单.md | 2 +- reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index d2201e80..3e17ea2d 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -685,7 +685,7 @@ **不做(待用户另裁)**:术语表 A 表词一族、doc-conventions 第 4 节流程动词一族、简明技术中文(STC)通用禁用词一族——三族的逐词计数与清单见卡片 §4「不做」表(本行不复制词面:06 正文引述禁词会自指引爆 doc_term 补充通道,判红)。 -**归属**:game/ 代码与数据表(代码域,走独立 worktree 批;并行避让——`changelog-retire-20261019` 在盘未合回且正在改 `AGENTS.md` 与 `design/engineering/code-conventions.md`,本批禁碰这两个文件,S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`) +**归属**:game/ 代码与数据表(代码域,走独立 worktree 批;`AGENTS.md` 与 `design/` 依流水线红线本批禁碰,S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`) **状态**:已写卡(reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md,**v1.3**)+已编迭代 32 diff --git a/reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md b/reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md index 483b9b68..0795f2b9 100644 --- a/reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md +++ b/reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md @@ -163,7 +163,7 @@ **明确不收**:①术语表「用语规范」A 表词面(`不得`/`报错`/`对标`/`若干`/`buff` 等)——§4 已列「不做」,收进来批末必然红;②单字「雷」——会误伤 64 处 / 26 个文件的保留词「排雷玩法/排雷规则」(内部机制名,§10 明定不扩大禁词面)。**禁止在脚本里另抄一份词表**(单一事实源红线,ADR 漂移教训同类)。A 表词/巢穴/旗将来若被裁决纳入,另行扩词表并单独立批清扫。 8. 🔴 **S11 必须带两道零命中自检**——①扫描面文件数为零即判红;②从术语表解析出的词面数为零即判红(沿 S3 教训:路径写歪或表格结构变了时,自检一起歪、一起红,不会静默恒绿)。 9. 🔴 **S11 闸门自指豁免**——命中行若属「检查禁用词本身」的闸门形态(行内含 `contains(`/`find(`/`grep`/`has_char(`/`禁「`/`禁『`/`零「`/`零『` 等检查或禁令表述),或含 `doc_term_audit.py` 同源的对照/历史信号,一律豁免、不判红。现存受此豁免的 5 处:`game/smoke/smoke_all.gd:1319`(禁字面检查逻辑)/`:1321`(零「雷/旗」断言描述)、`game/tests/unit/presentation/ui_font_asset_test.gd:18`/`:19`(字形覆盖夹具)、`game/data/tables/feats.tres:10`(desc 禁令引举)。**S11 规则说明自身与登记行一律用禁令引举句式**(如「禁「板级」「门票」……」)——既落 B2 对照性文本豁免,又天然触发本条自指豁免(否则闸本体的头注会被自己判红)。 -10. 🔴 **禁碰并行会话在改的文件**——`AGENTS.md` 与 `design/dev/code-conventions.md`(分支 `changelog-retire-20261019` 在盘未合回)。S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`。 +10. 🔴 **本批禁碰这两个文件**——`AGENTS.md`(根规则文件)与 `design/engineering/code-conventions.md`(在 `design/` 目录内):依据=迭代批禁写 `design/` 与根规则文件这条流水线红线(process-conventions §2),本批无例外。S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`。 11. 🔴 **对照性文本豁免**——含退役/更名/禁令等信号的行不改写(术语表用语规范 B 类豁免条款);本批的 B 类落点已全部显式枚举进 §2 豁免单,不再用行内子串现场判定。 12. 🔴 **parity 闸本批不发起、漂移记档、合回后另立重锚批**——N7 的 `_emit_row` 后移+`hl` 两态化会互换 `seal_miss`/`insurance_used` 两行的日志顺序并改写豁免态 `highlight`(`playtest_logger._on_step_row` 逐行落盘、七公共字段含 `highlight`),而 11 号闸对 JSONL 按 sha256 逐位比对——批准实跑必红,且闸令明载「不得借机重锚」。故本批 **不发起 parity**(回执落 NEED-APPROVAL:该态指纹记 skip、入 not_run,`all_green` 不受影响);预期漂移(豁免态/未豁免态各一例)写进实现报告「已记档差异」节;合回后另立**用户批准**的 parity 重锚批并登记 06,不得借任何批「顺手」重锚。N7 的行为正确性验收走 A10/A11/A12 正向断言(测试三层分工纪律①主力)。 @@ -190,7 +190,7 @@ | `design/` 全部文档(术语表/战斗结算/地图战斗资源/难度曲线与Boss/art-bible/ux 各件/07 清单) | **反哺点**——落 `reports/iter32-反哺点-<日期>.md`,由用户在会话裁决后归文档轨批(迭代批禁写 `design/`) | | `门票` 标识符与数据键(`feat_ticket_*`/`SHELF_KINDS`/存档键) | 上游卡 §4 明列不碰;若将来要改,另立独立批并连带处理存档兼容 | | `shop.tres:86`「奇物门票」与 `curio_interact_controller.gd:165-166` 玩家文案 | 属 奇物/专长 归类表述,与 06「冒记案遗留待裁两项」第①项同源 → 交文档侧定性后另走传导批 | -| `AGENTS.md`/`design/dev/code-conventions.md` | 并行会话 `changelog-retire-20261019` 在盘未合回,本批禁碰 | +| `AGENTS.md`/`design/engineering/code-conventions.md` | 本批禁碰——迭代批禁写 `design/` 与根规则文件(流水线既有红线,见契约 10) | | 术语表 A 表词(不得 14/报错 18/对标 1/若干 1/buff 22) | 待用户另裁;裁入则新立 06 条目与卡片 | | 「巢穴(机制表述)」换代与单字「旗」清理 | S11 显式排除单已收理由(巢穴=玩家专名 B3+风味层除外注;旗=doc_term_audit 既有判例+6 处全豁免);两项清理均需用户裁后另立批(06 登记) | | doc-conventions 第 4 节流程动词(收口 128/随批 20/台账 17/对拍 16/在飞 10/落文 2) | 同上 | @@ -396,7 +396,7 @@ 2. `.tres` 加载失败或 schema 不同步; 3. 改前改后同种子读数不一致; 4. S11 注入后不变红(判据无效); - 5. 触碰并行会话在改文件(`AGENTS.md`/`design/dev/code-conventions.md`); + 5. 触碰 `AGENTS.md` 或 `design/` 目录下任何文件(迭代批越界——流水线红线); 6. **N7 后移 `_emit_row` 后,奖励兑付结果与改前不一致**(说明改到了兑付行为,而非只改文案判据)。 --- From 85dce2c77de49f2bc831802e7315070d2a9be06b Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 20:35:14 +0800 Subject: [PATCH 23/59] =?UTF-8?q?feat(T1):=20S11=20=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E7=A6=81=E7=94=A8=E8=AF=8D=E8=A7=84=E5=88=99?= =?UTF-8?q?=E8=90=BD=E9=97=B8=E2=80=94=E2=80=94=E5=85=88=E8=90=BD=E8=A7=84?= =?UTF-8?q?=E5=88=99=E5=86=8D=E8=A7=81=E7=BA=A2=EF=BC=8889=20=E5=A4=84?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 按契约 6 先写 S11 规则并跑出红,为 T2–T6 批量换代提供回归网。 词表从术语表「退役词对照」节解析+显式追加完美排雷、排除巢穴/旗。 三层豁免(闸门自指/显式留档 4 处/非注释面天然不取)+两道自检。 --- game/tests/README.md | 6 +- game/tests/static_scan.sh | 117 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/game/tests/README.md b/game/tests/README.md index 77577154..4d2cf913 100644 --- a/game/tests/README.md +++ b/game/tests/README.md @@ -15,7 +15,7 @@ tests/ smoke/ # critical-paths.md——人工 gate 清单(/smoke-check 读取) evidence/ # 截图与人工签核记录 run_all.gd # 单元套件统一入口(套件 manifest 协议,D2 AC-2b) - static_scan.sh # 静态扫描域 S1–S8 可执行子集 + static_scan.sh # 静态扫描域 S1–S11 可执行子集 ``` ## 测试三层与承载目录 @@ -109,9 +109,11 @@ timeout 120s godot --headless --script tests/run_all.gd ## Static Scan(提交前本地跑) -`tests/static_scan.sh` 实现静态扫描域 S1–S8 的可执行子集;规则全集与动机见 +`tests/static_scan.sh` 实现静态扫描域 S1–S11 的可执行子集;规则全集与动机见 `design/engineering/architecture/architecture.md`「测试与质量域」节。新违规案例必须**先补扫描规则再修码**。 +S11 代码注释禁用词:扫描 game/ 全域 .gd/.tres/.md/.json/.sh 的注释面,词表从 `design/gdd/术语表.md`「退役词对照」解析(显式追加「完美排雷」,排除「巢穴」「旗」);三层豁免(闸门自指/显式留档 4 处/非注释面天然不取);两道自检(扫描面文件数非空+词表解析非空)。 + ## 本地闸(唯一验收门禁) 本仓库无远端、无 CI——**验收只在本地发生**,跑 `tools/run_all_gates.sh` 是收口唯一入口,按本批改动域选档(`--code`/`--docs`/跨两域或改闸件本身=不带参数全量), diff --git a/game/tests/static_scan.sh b/game/tests/static_scan.sh index 4cf5a2ce..0716a83f 100644 --- a/game/tests/static_scan.sh +++ b/game/tests/static_scan.sh @@ -93,4 +93,121 @@ fi # S7 B2/B3/B4 API 符号命中文件 ⊆ B1 文件集(编排唯一性) # S8 结算路径 await 零命中(B1 结算/编排文件集) +# ── S11 — 代码注释禁用词 ── +# 禁「板级」「门票」「正主」「落籍」「完美排雷」等退役词进注释面(完整词表见术语表解析) +# 权威出处:design/gdd/术语表.md「退役词对照」节+「对外命名纪律」节 +# 扫描面:game/ 全域 .gd/.tres/.md/.json/.sh(.txt 不收=第三方许可证非本仓库文本) +# 词表来源:解析「退役词对照」第一列(去括号注、斜杠拆分)+显式追加「完美排雷」;显式排除「巢穴」(玩家专名/风味层,术语表自带除外注)、「旗」(单字误报率高,doc_term_audit 判例) +# 注释文本提取:.gd/.sh 取 # 后文本;.tres 取 ; 后文本;.md 取整行;.json 无注释语法(保留扩展名但不产生注释段) +# 三层豁免依序:①闸门自指(行内含检查/禁令形态即跳过)②显式留档豁免单 4 处 ③非注释面天然不取 + +if [ -d game/core ]; then +S11_TABLE="design/gdd/术语表.md" +S11_FAIL_LOCAL=0 + +if [ ! -f "$S11_TABLE" ]; then + echo "[static_scan] S11 FAIL: 术语表文件不存在($S11_TABLE)" + S11_FAIL_LOCAL=1 +else + # 解析词表:「退役词对照」第一列→去括号注→斜杠拆分 + S11_WFILE=$(mktemp) + awk '/^## 退役词对照/{f=1;next} f && /^## /{exit} f && /^\|/ && !/^\|---/ && !/退役词/{ + sub(/^\| */, ""); sub(/ *\|.*/, "") + gsub(/([^)]*)/, ""); gsub(/\([^)]*\)/, "") + gsub(/^ *| *$/, "") + n = split($0, parts, " / ") + for (i=1;i<=n;i++){gsub(/^ *| *$/,"",parts[i]); if(parts[i]!="") print parts[i]} + }' "$S11_TABLE" > "$S11_WFILE" + # 显式追加+排除 + printf '完美排雷\n' >> "$S11_WFILE" + grep -vx '巢穴' "$S11_WFILE" | grep -vx '旗' | grep -vx 'flag_\*' | sort -u > "${S11_WFILE}.x" && mv "${S11_WFILE}.x" "$S11_WFILE" + + # 自检二:词表解析非空 + S11_WC=$(grep -c . "$S11_WFILE" 2>/dev/null || echo 0) + if [ "$S11_WC" -eq 0 ]; then + echo "[static_scan] S11 FAIL: 词表解析为空——术语表结构可能已变" + S11_FAIL_LOCAL=1 + fi + + # 自检一:扫描面非空 + S11_FC=$(find game/ -type f \( -name '*.gd' -o -name '*.tres' -o -name '*.md' -o -name '*.json' -o -name '*.sh' \) 2>/dev/null | wc -l) + if [ "$S11_FC" -eq 0 ]; then + echo "[static_scan] S11 FAIL: 扫描面为空——路径写错导致的静默空转" + S11_FAIL_LOCAL=1 + fi + + if [ "$S11_FAIL_LOCAL" -eq 0 ]; then + # 扫描三个文件类型并合并结果 + S11_ALL_HITS=$( + # .gd/.sh:取 # 后注释 + find game/ -type f \( -name '*.gd' -o -name '*.sh' \) -print0 2>/dev/null \ + | xargs -0 awk -v wf="$S11_WFILE" ' + BEGIN{nw=0;while((getline w0)words[++nw]=w;close(wf)} + /#/{ + cs=index($0,"#"); cmt=substr($0,cs+1) + for(i=1;i<=nw;i++){ + if(index(cmt,words[i])>0){ + if($0~/contains\(|find\(|grep|has_char\(|禁「|禁『|零「|零『/)next + if(FILENAME~"enemy.tres"&&NR==653)next + if(FILENAME~"level_runner"&&NR==832)next + if(FILENAME~"adventure_runner"&&NR==403)next + if(FILENAME~"damage_math_test"&&NR==36)next + print FILENAME":"NR":"words[i] + next + } + } + } + ' 2>/dev/null + # .tres:取 ; 后注释 + find game/ -type f -name '*.tres' -print0 2>/dev/null \ + | xargs -0 awk -v wf="$S11_WFILE" ' + BEGIN{nw=0;while((getline w0)words[++nw]=w;close(wf)} + /;/{ + cs=index($0,";"); cmt=substr($0,cs+1) + for(i=1;i<=nw;i++){ + if(index(cmt,words[i])>0){ + if($0~/contains\(|find\(|grep|has_char\(|禁「|禁『|零「|零『/)next + if(FILENAME~"enemy.tres"&&NR==653)next + print FILENAME":"NR":"words[i] + next + } + } + } + ' 2>/dev/null + # .md:整行即注释面 + find game/ -type f -name '*.md' -print0 2>/dev/null \ + | xargs -0 awk -v wf="$S11_WFILE" ' + BEGIN{nw=0;while((getline w0)words[++nw]=w;close(wf)} + { + for(i=1;i<=nw;i++){ + if(index($0,words[i])>0){ + if($0~/contains\(|find\(|grep|has_char\(|禁「|禁『|零「|零『/)next + print FILENAME":"NR":"words[i] + next + } + } + } + ' 2>/dev/null + ) + S11_HITS=0 + if [ -n "$S11_ALL_HITS" ]; then + S11_HITS=$(echo "$S11_ALL_HITS" | grep -c .) + fi + + if [ "$S11_HITS" -gt 0 ]; then + echo "[static_scan] S11 FAIL: 代码注释禁用词命中 $S11_HITS 处" + echo "$S11_ALL_HITS" | head -50 + if [ "$S11_HITS" -gt 50 ]; then echo " ...(截断,共 $S11_HITS 处)"; fi + fail=1 + else + echo "[static_scan] S11 ok(扫描面 $S11_FC 个文件,词表 $S11_WC 词)" + fi + else + fail=1 + fi + + rm -f "$S11_WFILE" +fi +fi + exit $fail From b6629d684814b7d511e227c35d097a9ef6cdf219 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 20:41:50 +0800 Subject: [PATCH 24/59] =?UTF-8?q?feat(T2-T6):=20=E4=BA=94=E8=AF=8D?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E6=8D=A2=E4=BB=A3=E2=80=94=E2=80=94=E5=AE=8C?= =?UTF-8?q?=E7=BE=8E=E6=8E=92=E9=9B=B7=E2=86=92=E5=AE=8C=E7=BE=8E=E5=B0=81?= =?UTF-8?q?=E5=8D=B0/=E6=9D=BF=E7=BA=A7=E2=86=92=E6=95=B4=E5=9B=BE/?= =?UTF-8?q?=E9=97=A8=E7=A5=A8=E2=86=92=E4=B8=93=E9=95=BF=E5=87=AD=E8=AF=81?= =?UTF-8?q?/=E6=AD=A3=E4=B8=BB=E2=86=92=E7=8E=B0=E8=A1=8C=E4=BA=8B?= =?UTF-8?q?=E5=AE=9E=E6=BA=90/=E8=90=BD=E7=B1=8D=E2=86=92=E5=B7=B2?= =?UTF-8?q?=E5=85=A5=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 全局 sed 替换 89 处命中清零(S11 绿)。修复: - 移交 3 处保留原词(shop.tres:86 display_name、curio_controller:165-166 玩家文案) - 豁免 enemy.tres:653 历史注记保持"已落籍" - static_scan.sh 词表追加行与头注恢复禁「」引举句式 - S11 规则文件自身不被自身规则误伤(闸门自指豁免生效) --- game/core/adventure_runner.gd | 24 ++++++------- game/core/battle_orchestrator.gd | 24 ++++++------- game/core/board_data.gd | 4 +-- game/core/config_db.gd | 14 ++++---- game/core/config_db_cross_validator.gd | 2 +- game/core/level_runner.gd | 10 +++--- game/core/minesweeper_rules.gd | 2 +- game/core/treasure_items.gd | 8 ++--- game/data/schemas/adventure_table.gd | 6 ++-- game/data/schemas/settlement_table.gd | 2 +- game/data/schemas/shop_table.gd | 2 +- game/data/schemas/variation_table.gd | 4 +-- game/data/tables/shop.tres | 2 +- .../presentation/curio_interact_controller.gd | 6 ++-- game/presentation/hud_presenter.gd | 4 +-- game/presentation/main.gd | 2 +- game/presentation/row_pacer.gd | 2 +- .../treasure_interact_controller.gd | 2 +- game/presentation/views/battle_log_view.gd | 2 +- game/presentation/views/board_cell_unit.gd | 6 ++-- game/presentation/views/board_fx_view.gd | 6 ++-- game/presentation/views/board_view.gd | 10 +++--- game/presentation/views/curio_pick_overlay.gd | 2 +- .../views/hero_info_panel_view.gd | 4 +-- game/presentation/views/settlement_fx_view.gd | 4 +-- game/smoke/board_shot_probe.gd | 2 +- game/smoke/layout_probe.gd | 2 +- game/smoke/level_autoplay.gd | 2 +- game/smoke/shot_probe.gd | 4 +-- game/smoke/smoke_all.gd | 34 +++++++++---------- game/smoke/t17_defer_probe.gd | 4 +-- game/smoke/ui_input_probe.gd | 2 +- game/tests/README.md | 2 +- game/tests/smoke/critical-paths.md | 2 +- game/tests/static_scan.sh | 20 +++++------ game/tests/unit/core/feat_vouchers_test.gd | 2 +- game/tests/unit/core/pool_case_d_test.gd | 2 +- game/tests/unit/data_config/config_db_test.gd | 2 +- .../unit/presentation/reward_overlay_test.gd | 2 +- 39 files changed, 118 insertions(+), 118 deletions(-) diff --git a/game/core/adventure_runner.gd b/game/core/adventure_runner.gd index b7e1462d..5c9b031c 100644 --- a/game/core/adventure_runner.gd +++ b/game/core/adventure_runner.gd @@ -56,7 +56,7 @@ var _time_sand_queue := 0 # 时沙待注入(回合级——下 var _save_manager = null # 断点承载注入(null = 不写断点;模拟/冒烟缺省) var _resume_bp := {} # 续玩快照暂存(resume_adventure → _start_current_level 单跳传递) # ---- 三选一停点态 ---- -var _curio_taken := {} # 件获取次数计数(kind 维度派生账本——断点附随件与摘要读数承载;池库存正主=_curio_deck) +var _curio_taken := {} # 件获取次数计数(kind 维度派生账本——断点附随件与摘要读数承载;池库存现行事实源=_curio_deck) var _curio_deck: Array[Variant] = [] # 令牌池(TP0 v2.2——持久多重集,元素 {"kind","tier"};洗牌抽候选/选中踢池未选回池/池耗即枯竭;商店货架同库共账;规则改写型特性带=relic 令牌随表追加) var _feats: Array[String] = [] # 特性持有集(局内随机渠道获得、冒险级跨关携带、收束清零;🔴 层级纪律承载面:不入同调位不入局外树) var _tree_rules: Array[Variant] = [] # 树 rule 键集(Fork 激活侧 effects 透传;下传 enc.tree_rules 消费面) @@ -64,9 +64,9 @@ var _curio_pending := {} # 停点态:{"candidates": Array, "p var _curio_result := {} # 已兑付待推进态(curio_resolved 载荷副本——中断续玩不重兑付) var _keystone_drops: Array[Variant] = [] # Boss 逐杀掉落明细(additive 摘要键 keystone_drops——结算明细/复盘归因数据源) var _node_curio_pending := {} # 奖励节点三选一停点态(共享池;断点不载:续玩重建到选路停点重走,恢复的计数器保证同候选重抽) -var _feat_ticket_pity := 0 # 门票保底计数(T5——展示次数:节点开面/货架抽签/刷新重展各计一次;触发清零) -var _feat_ticket_sold := 0 # 门票限购计数(T5——选中/买下即 +1;拿到即开不进持有集) -var _feat_ticket_appeared := 0 # 门票出现计数(T5——quota 上限面) +var _feat_ticket_pity := 0 # 专长凭证保底计数(T5——展示次数:节点开面/货架抽签/刷新重展各计一次;触发清零) +var _feat_ticket_sold := 0 # 专长凭证限购计数(T5——选中/买下即 +1;拿到即开不进持有集) +var _feat_ticket_appeared := 0 # 专长凭证出现计数(T5——quota 上限面) var _shop_mode := "legacy" # 商店模式("legacy"=固定三件加定价〔off 对照承载,缺省零扰动〕/"pool"=共享池抽 3 买 1 重抽;真实入口 main.gd 显式投 pool) @@ -472,7 +472,7 @@ func pool_stock(kind: String) -> int: # 未知 kind 拒绝(货架词表封闭的前置防御)。 func _consume_pool_purchase(kind: String, tier: String) -> bool: if kind == "feat_ticket": - return _redeem_feat_ticket() # T5——门票买下即开(零摘牌不进持有集;临时停点开专长三选一面) + return _redeem_feat_ticket() # T5——专长凭证买下即开(零摘牌不进持有集;临时停点开专长三选一面) if not db.adventure.CURIO_KINDS.has(kind): push_error("[冒险结构] 商店购买消费拒绝——件不在池词表: %s" % kind) return false @@ -659,7 +659,7 @@ func _finish_node_bonus(picked: String, value: int, tier: String = "", feat_id: # 自动回池;池耗即枯竭——余库不足 N kind 时出齐剩余,空库 = 零候选合法态)。候选 = 令牌字典 # {"kind","tier"}。消费 reward_pick 封闭流——一次停点恰一 scope,同种子同候选。 # 渠道白名单过滤(渠道轴定位:关底 Boss 击败=通关渠道只出专长(feat 令牌); -# 奖励节点/商店只出属性值提升+资源(非 relic 令牌),专长在非 Boss 渠道只以门票形态出现(T5)。 +# 奖励节点/商店只出属性值提升+资源(非 relic 令牌),专长在非 Boss 渠道只以专长凭证形态出现(T5)。 # 过滤式而非物理拆池:deck 物理结构/存档键 bonus_deck 混编余库/消耗语义(选中踢池未选回池)原样, # 白名单在候选视图层生效——配额结构锚 TIER_QUOTAS 70/25/3=98 零改动(专长令牌本系活行追加面,在锚外)。 # 曝光槽:非 Boss 渠道三选一 = **2 格全池 + 1 格优秀档以上子池** @@ -746,7 +746,7 @@ func _draw_curio_candidates(channel: String = "reward_node") -> Array: sub = [] # 子池枯竭——曝光槽回退全池续取 continue break # 全池枯竭——出齐剩余(池空直通同族兜底) - # T5 门票注入(非 Boss 渠道唯一专长入口——替换末位候选占一席,候选数不变;判定含 pity 清零记账) + # T5 专长凭证注入(非 Boss 渠道唯一专长入口——替换末位候选占一席,候选数不变;判定含 pity 清零记账) if channel == "reward_node" and not out.is_empty() and _feat_ticket_consider(rg): out[out.size() - 1] = {"kind": "feat_ticket", "tier": "excellent"} return out @@ -766,7 +766,7 @@ func _curio_cap_ok(kind: String, feat_id: String = "") -> bool: return int(_curio_taken.get(kind, 0)) < cap -# —— 专长获取门票(T5——非 Boss 渠道的专长入口;四口径契约④:拿到即开不可囤积/ +# —— 专长获取专长凭证(T5——非 Boss 渠道的专长入口;四口径契约④:拿到即开不可囤积/ # 罕见只在概率不在价格/一局限购一次/计步保底连续 5 展示未出第 6 必出——计数=展示次数、刷新 # 重展计入、节点与商店共享、触发清零、限购满不再触发。调用即一次展示判定与记账)—— func _feat_ticket_consider(rg: RandomNumberGenerator) -> bool: @@ -783,7 +783,7 @@ func _feat_ticket_consider(rg: RandomNumberGenerator) -> bool: return offer -# 门票兑付(拿到即开——停点候选替换为专长三选一;不进持有集/零摘牌;限购计数 +1): +# 专长凭证兑付(拿到即开——停点候选替换为专长三选一;不进持有集/零摘牌;限购计数 +1): # 节点停点=本地替换(呈现层读在途态重绘);店内无停点=临时停点 + payload.context 标记(呈现层 # 重 present 无胜利总结面,确认后只关面回店)。 func _redeem_feat_ticket() -> bool: @@ -791,7 +791,7 @@ func _redeem_feat_ticket() -> bool: _feat_ticket_pity = 0 var cands: Array[Variant] = _draw_curio_candidates("level_clear") # 专长池(与通关渠道同白名单) if cands.is_empty(): - push_error("[冒险结构] 门票兑付失败——专长池空集") + push_error("[冒险结构] 专长凭证兑付失败——专长池空集") _feat_ticket_sold -= 1 return false if not _node_curio_pending.is_empty(): @@ -1028,8 +1028,8 @@ func _snapshot_breakpoint() -> void: "bonus_deck": _curio_deck.duplicate(true), # 令牌池余库(TP0 v2.2——池消耗即上限,续玩余库逐枚还原) "relics": _feats.duplicate(), # 特性持有集(局内随机渠道获得态续玩防丢失) "bonus_pending": _curio_pending.duplicate(true), # 三选一停点态(空 = 无停点——选择停点可中断契约) - "feat_ticket_pity": _feat_ticket_pity, # T5 门票保底计数(扩列向后兼容——旧档缺键缺省 0) - "feat_ticket_sold": _feat_ticket_sold, # T5 门票限购计数(同上) + "feat_ticket_pity": _feat_ticket_pity, # T5 专长凭证保底计数(扩列向后兼容——旧档缺键缺省 0) + "feat_ticket_sold": _feat_ticket_sold, # T5 专长凭证限购计数(同上) "adventure_counters": run_ledger.adventure_counters.duplicate(true), # adventure 域计数器随断点(续玩跨战账不丢) "vision_counter_used": int(run_ledger.vision_counter.get("used", 0)), # 真视使用计数随断点(续玩跨战账不丢) "refresh_stock": _refresh_stock, # 刷新存量账随断点 diff --git a/game/core/battle_orchestrator.gd b/game/core/battle_orchestrator.gd index b2eb54c7..ff672721 100644 --- a/game/core/battle_orchestrator.gd +++ b/game/core/battle_orchestrator.gd @@ -62,7 +62,7 @@ var _verdict_seg = null # VerdictSegment(⑤判定段——返回裁定, var _refresh_used_this_round := 0 # 每轮刷新计数(Active 相位合计,兜底上限 = ActionEconomyTable.refresh_cap_per_round) var _board_seq := 0 # 板序号(本战斗第几张板——快照归因用) var _board_from_midround_refresh := false # 装板 provenance:轮内刷新换来的图 = true(清图奖励守卫——刷新图不发清图奖励) -var _seal_consumed := {} # 兑付资格以危险格实例为键(板级;换图重置) +var _seal_consumed := {} # 兑付资格以危险格实例为键(整图;换图重置) # 同调装配运行态(begin_battle 经 enc.attunement 注入;off=空集全部效果零扰动) var attunement: Array[Variant] = [] # 装备中同调件 item_id 集 var _ledger: RunLedger = null # 共享四本账(begin_battle 经 enc["ledger"] 持引用;缺省新账=调试面) @@ -259,7 +259,7 @@ func attune_convert_state() -> Dictionary: # 流派档位质变=FeatsEngine 纯函数求值 # (档位机制本身系引擎基建非内容效果),两运行态注伤害控制器:档一 rider+1 / 档二 rider 可暴击) var _seal_miss_seen := {} # 封印未中行去重(每安全格实例一次) -var _perfect_hit_true := 0 # 板级完美排雷计数(install 重置) +var _perfect_hit_true := 0 # 整图完美封印计数(install 重置) var _perfect_hit_false := 0 var _perfect_forgiven := 0 # 完美保险豁免累计(单向累加自有账;契约 2 禁改写 _perfect_hit_false) var _hero_atk := 0 # 主角攻击基值快照(encounter.hero_atk;E4 收口——表值运行期不可变) @@ -439,7 +439,7 @@ func _install_new_board(during_round := false) -> bool: # 全局作用域变异决议(装板序内前置于 roll_board:图级偏斜旋钮须在资源 # 摇号前定型;全局门控与板无关〔节点身份+unlock+board_types〕,确定性取用零取号)。 # boss/elite 图命中全局型 → 写 board_variants(_place_variants 见非空即跳 region=替换制); - # 全局池空 → 板级字段留空(_place_variants 原路走 region=兜底回落合法态)。 + # 全局池空 → 整图字段留空(_place_variants 原路走 region=兜底回落合法态)。 _resolve_global_variant(board) var res: Dictionary[Variant, Variant] = minesweeper.install_board(board, during_round) if not res.accepted: @@ -464,7 +464,7 @@ func _install_new_board(during_round := false) -> bool: _place_variants(board) _seal_consumed.clear() # 换图新雷 = 新实例,资格自然重置(行动经济 Rule 8) _seal_miss_seen.clear() - _perfect_hit_true = 0 # 板级完美计数随 install 重置 + _perfect_hit_true = 0 # 整图完美计数随 install 重置 _perfect_hit_false = 0 _perfect_forgiven = 0 # 豁免累计随 install 重置(domain=battle 每战清零) _board_from_midround_refresh = during_round # 轮内刷新装板 = 刷新图(清图奖励不发);常规换图/开战装板 = false @@ -476,7 +476,7 @@ func _install_new_board(during_round := false) -> bool: # ---- 全局作用域变异 决议(装板序内 roll_board 之前)---- -# boss/elite 图命中全局型:写板级 board_variants(恰一行)+ 注入资源面偏斜旋钮(图级投影在 +# boss/elite 图命中全局型:写整图 board_variants(恰一行)+ 注入资源面偏斜旋钮(图级投影在 # RewardEconomy.roll_board 消费);不消费 variant_place 流(全局取用确定性——零取号合法态)。 # 全局池空(含 L1 Boss 免疫/unlock 门控未达):字段留空、旋钮归零——_place_variants 原路走 # region 布置 = 兜底回落(保守向后兼容,防配置缺行静默裸奔——provisional)。 @@ -500,8 +500,8 @@ func _resolve_global_variant(board: BoardData) -> void: # (关卡序号−1)×per_level_bonus——基数为候选池而非总格数(初始展开 # 占全板 56–67%,总格数基数使有效密度膨胀 4–6 倍、L1 小板极端全池覆盖;percent 语义 = 占可挖格比例, # 关卡递增由 per_level_bonus 绝对格数承载);连通片生长(8 邻),单片 ≤ pack_max(2×2 / 1×4 / 1×3+1 等形)。 -# 替换制(全局作用域变异):板级 board_variants 非空 = 本图已带全局型,跳过 region -# 布置(每图一型的板级推广:普通图=region,Boss/精英图=global);空 = 原路径(含 Boss 图全局池空回落)。 +# 替换制(全局作用域变异):整图 board_variants 非空 = 本图已带全局型,跳过 region +# 布置(每图一型的整图推广:普通图=region,Boss/精英图=global);空 = 原路径(含 Boss 图全局池空回落)。 func _place_variants(board: BoardData) -> void: if not board.board_variants.is_empty(): return @@ -905,7 +905,7 @@ func _submit_flat_hero(source_class: String, display: String, power: int, cell: # 封印判定批:标中 = 该危险格资源的正向兑付(每雷实例一次;高光 = 强制检查点); # 标空 = "封印未中"归因行 + 该安全格资源的负向兑付(同键去重——每格实例一次)。 -# 清图批:清图奖励对象恰好发一次;完美排雷追加第二份同身份兑付(grant_clear 本身恰一次)。 +# 清图批:清图奖励对象恰好发一次;完美封印追加第二份同身份兑付(grant_clear 本身恰一次)。 # 高光行 value = 实际有效兑付份数(禁记名义值;首份零兑付 → 降级不发)。 func _grant_clear_reward(ri: int) -> void: if _board_from_midround_refresh: @@ -919,10 +919,10 @@ func _grant_clear_reward(ri: int) -> void: if perfect and first_ok: second_ok = _grant_clear_identity(snap, ri, "(完美第二份)") if perfect and first_ok: - _emit_row("highlight", "clear_reward", Vector2i(-1, -1), ri, "完美排雷!清图奖励 ×2", (2 if second_ok else 1), {}, "perfect_sweep") + _emit_row("highlight", "clear_reward", Vector2i(-1, -1), ri, "完美封印!清图奖励 ×2", (2 if second_ok else 1), {}, "perfect_sweep") -# 清图奖励 = 板级独立对象(不属于任何一格):兑付形态按其 cell_type 的正向字典形态走, +# 清图奖励 = 整图独立对象(不属于任何一格):兑付形态按其 cell_type 的正向字典形态走, # 行值全部取快照(身份批 roll 值)。返回实际有效兑付。 # 同步开单(sync)——完美第二份与高光份数的流程依赖需要同步读数(开单权归流程); # 同步路径内先按序结清段内排队单据(B 模式保序),随后本批无视结账政策当场兑现。 @@ -1206,7 +1206,7 @@ func presentation_snapshot() -> Dictionary: "hero": hero, "enemies": enemies, "hero_effects": _status_effects.query_active("hero").duplicate(true), # 值拷贝出户(快照消费方直改不渗入状态容器) - # 板级变异投影(呈现横幅/常驻角标唯一读取面; + # 整图变异投影(呈现横幅/常驻角标唯一读取面; # 空数组 = 无全局型合法态:普通图与全局池空回落图恒空) "board_variants": (minesweeper.current_board().board_variant_ids().duplicate() if minesweeper.current_board() != null else ([] as Array[String])), @@ -1289,7 +1289,7 @@ func _fatal(msg: String) -> void: assert(false, msg) -## 完美排雷谓词(两账相减:有效误标=误标总数−豁免数) +## 完美封印谓词(两账相减:有效误标=误标总数−豁免数) ## 契约 2:_perfect_hit_false 保持纯净,豁免只累加 _perfect_forgiven,禁回退式改写与拦截式吞事件。 func perfect_sweep_earned() -> bool: return _perfect_hit_false - _perfect_forgiven <= 0 and _perfect_hit_true >= 1 diff --git a/game/core/board_data.gd b/game/core/board_data.gd index 872f3e88..c1539e62 100644 --- a/game/core/board_data.gd +++ b/game/core/board_data.gd @@ -14,7 +14,7 @@ var spawn_center := Vector2i.ZERO var mines := {} # Vector2i → true var digits := {} # Vector2i → int(安全格恒有值;数字恒真 = 8 邻雷数) var variants := {} # Vector2i → Array[String](生成期快照,抗表重载) -var board_variants: Array[String] = [] # 板级变异 id 集(scope=global 整图作用域—— +var board_variants: Array[String] = [] # 整图变异 id 集(scope=global 整图作用域—— # 战斗编排装板决议写入,随图生灭同 variants;普通图恒空) var board_type := "" # 图类型标签(词表 v1.0:dungeon/underdark;玩家侧显示名「地图类型」) var level_index: int = 1 @@ -50,7 +50,7 @@ func variant_ids(c: Vector2i) -> Array: return variants.get(c, []) -# 板级变异只读出口(scope=global 行集——呈现快照/断言消费;空 = 无全局型合法态) +# 整图变异只读出口(scope=global 行集——呈现快照/断言消费;空 = 无全局型合法态) func board_variant_ids() -> Array[String]: return board_variants diff --git a/game/core/config_db.gd b/game/core/config_db.gd index db0ddc0c..95749262 100644 --- a/game/core/config_db.gd +++ b/game/core/config_db.gd @@ -19,8 +19,8 @@ const TABLE_MANIFEST := { "settlement": "settlement.tres", "level": "level.tres", "difficulty": "difficulty.tres", - "shop": "shop.tres", # ShopTable(表与 schema 落籍归数据面——本处只接线加载与消费) - "meta": "meta.tres", # MetaTable 四行族(schema 与表同源落籍) + "shop": "shop.tres", # ShopTable(表与 schema 已入库归数据面——本处只接线加载与消费) + "meta": "meta.tres", # MetaTable 四行族(schema 与表同源已入库) "meta_tree": "meta_tree.tres", # MetaTreeTable 12 节点(定义表 Rule 4 豁免——天赋树.md v0.8 结构事实源) "treasure_items": "treasure_items.tres", # TreasureItemTable 六行(定义表 Rule 4 豁免;罗盘 retired/失义件 deferred 标记见 schema 头注) "adventure": "adventure.tres", # AdventureTable(大奖励与钥石行值单点) @@ -39,10 +39,10 @@ var reward: RewardTable var settlement: SettlementTable var level: LevelTable var difficulty: DifficultyTable -# ShopTable 类型化持用(schema class_name 已落籍; +# ShopTable 类型化持用(schema class_name 已已入库; # 消费面一律走下方 shop_* 访问器,禁直读行集) var shop: ShopTable = null -# MetaTable 类型化持用(schema 与表同源落籍) +# MetaTable 类型化持用(schema 与表同源已入库) var meta: MetaTable var meta_tree: MetaTreeTable # 类型化持用(消费面走 tree_node 访问器) var treasure_items: TreasureItemTable # 类型化持用(消费面走 treasure_* 访问器) @@ -277,7 +277,7 @@ func treasure_attunement_rows() -> Array: # 行族四轴(数据契约,行集归 shop.tres):gp_drops {tier, mean, roll_min, roll_max} · # level_gp_bonus {level_index, bonus} · products {product_id, display_name, attr, flat_value, # base_price, price_increment} · price_level_bonus {level_index, bonus}。 -# 行族经 ShopTable 同名数组属性读取(.get 容缺——表落籍前查询恒空,掉落按 0 兑付的兜底在调用方)。 +# 行族经 ShopTable 同名数组属性读取(.get 容缺——表已入库前查询恒空,掉落按 0 兑付的兜底在调用方)。 func shop_gp_drop_row(tier: String) -> Dictionary: for row in _shop_rows("gp_drops"): @@ -334,7 +334,7 @@ func shop_price_b() -> float: return float(shop.price_b) if shop != null else 0.0 -# 行族数组读取(ShopTable 属性名 = 行族名;表未落籍/属性缺失 = 空集非错误态) +# 行族数组读取(ShopTable 属性名 = 行族名;表未已入库/属性缺失 = 空集非错误态) func _shop_rows(family: String) -> Array: if shop == null: return [] @@ -387,7 +387,7 @@ func _meta_rows(family: String) -> Array: # 设计权威 design/gdd/systems/跨局循环/锻造工坊.md v0.6:默认值归本表常驻持有(hero.tres 两轴已删—— # 契约 2);路线行族=攻防数值成长唯一数据面(契约 1)。数值全 provisional 归 M4。 -# 两根类型轴默认值(表未落籍=裸体态兜底 normal/light——与 ForgeTable 缺省值同口径) +# 两根类型轴默认值(表未已入库=裸体态兜底 normal/light——与 ForgeTable 缺省值同口径) func forge_default_attack_type() -> String: return String(forge.default_attack_type) if forge != null else "normal" diff --git a/game/core/config_db_cross_validator.gd b/game/core/config_db_cross_validator.gd index 670da120..7ba5f18e 100644 --- a/game/core/config_db_cross_validator.gd +++ b/game/core/config_db_cross_validator.gd @@ -97,7 +97,7 @@ func cross_validate(loaded: Dictionary, push_diag: Callable) -> void: for row in shp.pool_shelf: var kind: String = String(row.get("kind_id", "")) if kind == "feat_ticket": - continue # 门票豁免——货架专属机制种(非 deck 池种,零摘牌拿到即开),不入 CURIO_KINDS + continue # 专长凭证豁免——货架专属机制种(非 deck 池种,零摘牌拿到即开),不入 CURIO_KINDS if not adv.CURIO_KINDS.has(kind): push_diag.call("error", "shelf_dangling_kind", "ShopTable.pool_shelf kind %s 不在 AdventureTable.CURIO_KINDS(共享池牌库外种)" % kind) continue diff --git a/game/core/level_runner.gd b/game/core/level_runner.gd index e00129e8..e304c378 100644 --- a/game/core/level_runner.gd +++ b/game/core/level_runner.gd @@ -48,7 +48,7 @@ var _hero_armor_type := "" var _shop_pool_mode := false # pool 模式封印(set_shop_pool 注入时置位——AdventureRunner 按 params.shop_mode 下传) var _pool_deck: Array[Variant] = [] # 共享池令牌库共享引用(AdventureRunner._curio_deck——库存=剩余令牌数单点) var _pool_consume := Callable() # 池消费 handler(AdventureRunner._consume_pool_purchase——_apply_curio_pick 同口写加算区+账本+摘牌) -var _pool_ticket := Callable() # 门票展示判定 handler(T5——AdventureRunner._feat_ticket_consider;节点与商店共享计数) +var _pool_ticket := Callable() # 专长凭证展示判定 handler(T5——AdventureRunner._feat_ticket_consider;节点与商店共享计数) var _pool_cap_check := Callable() # cap 检查回调(AdventureRunner._curio_cap_ok;cap 满剔出货架候选视图) var _shop_shelf: Array[Variant] = [] # 当前货架(进店抽 3/买后全重抽——令牌字典 {"kind","tier"} 序,同 kind 去重每 kind 至多一卡) var _shop_visit_buys := 0 # 本次进店已购次数(A 链定价输入——离开清零) @@ -775,7 +775,7 @@ func player_request_refresh() -> bool: func set_shop_pool(deck_ref: Array, consume_handler: Callable, ticket_consider: Callable = Callable(), cap_check: Callable = Callable()) -> void: _pool_deck = deck_ref _pool_consume = consume_handler - _pool_ticket = ticket_consider # T5——门票展示判定(AdventureRunner._feat_ticket_consider;同流取数复用 shop_draw scope) + _pool_ticket = ticket_consider # T5——专长凭证展示判定(AdventureRunner._feat_ticket_consider;同流取数复用 shop_draw scope) _pool_cap_check = cap_check _shop_pool_mode = true @@ -820,12 +820,12 @@ func _shop_draw_shelf() -> void: _shop_shelf.append(tok) if _shop_shelf.size() >= 3: break - # T5 门票注入(非 Boss 渠道唯一专长入口——货架与节点共享保底计数;判定含 pity 记账,替换末位占一席。 + # T5 专长凭证注入(非 Boss 渠道唯一专长入口——货架与节点共享保底计数;判定含 pity 记账,替换末位占一席。 # 取数复用本函数 shop_draw scope 的 stream——零新 scope,确定性序列不漂移) if _pool_ticket.is_valid() and not _shop_shelf.is_empty() and bool(_pool_ticket.call(stream)): - _shop_shelf[_shop_shelf.size() - 1] = {"kind": "feat_ticket", "tier": "excellent"} # 门票占位档名 = excellent + _shop_shelf[_shop_shelf.size() - 1] = {"kind": "feat_ticket", "tier": "excellent"} # 专长凭证占位档名 = excellent # 商店渠道无专长直接投放(渠道白名单:商店渠道只出属性值提升+资源,专长在非 Boss - # 渠道只以门票形态出现——奇物.md v2.7/A4 断言;专长商店入口=T5 门票)。 + # 渠道只以专长凭证形态出现——奇物.md v2.7/A4 断言;专长商店入口=T5 专长凭证)。 # 库存余量(TP0——令牌库内该 kind 剩余枚数单点读;未注入/防御读 = 0) diff --git a/game/core/minesweeper_rules.gd b/game/core/minesweeper_rules.gd index 3da13158..2db833ac 100644 --- a/game/core/minesweeper_rules.gd +++ b/game/core/minesweeper_rules.gd @@ -123,7 +123,7 @@ func install_board(b: BoardData, during_round := false) -> Dictionary: _spawn = {} for c in b.spawn_cells(): _spawn[c] = true - # 初始展开:O₀ = R₀ 恰等(免费/计入清图/无格面资源/永不触雷);板级一次跨轮不重放 + # 初始展开:O₀ = R₀ 恰等(免费/计入清图/无格面资源/永不触雷);整图一次跨轮不重放 for c in _initial_expansion_order(b): _revealed[c] = {"kind": "safe", "digit": b.digit_of(c)} cell_revealed.emit({ diff --git a/game/core/treasure_items.gd b/game/core/treasure_items.gd index 6f39db90..e3ec1fc6 100644 --- a/game/core/treasure_items.gd +++ b/game/core/treasure_items.gd @@ -1,5 +1,5 @@ ## VERTICAL SLICE - NOT FOR PRODUCTION -## 秘宝关卡域库存+板级叠加层:全程零随机零特判,同操作序列重放库存与叠加层投影逐位相同(垂直切片验证:道具全程确定性)。 +## 秘宝关卡域库存+整图叠加层:全程零随机零特判,同操作序列重放库存与叠加层投影逐位相同(垂直切片验证:道具全程确定性)。 ## Used 不可逆——consume 后保留只读,枚举序=受理序;库存关卡域跨战斗延续、关卡末清空,叠加层随图消亡(清空编排归调用方,本类只供 clear/reset/retire_overlays)。 ## 零特判纪律:本类不写任何其他系统状态,排雷玩法代码零本系统分支;相位检查归战斗编排 use_treasure——validate_use 是纯谓词零消耗。 class_name TreasureItems @@ -38,7 +38,7 @@ func add_item(item_id: String, source_class: String, cell: Vector2i, round_index # ---- 库存读面(C 区槽位常读)---- -# 枚举序=受理序;Used 保留只读;逐件含 usable 板级零信息预判(调用方喂板面回调) +# 枚举序=受理序;Used 保留只读;逐件含 usable 整图零信息预判(调用方喂板面回调) func query_inventory(board_has_preview_info: Callable) -> Array: var out: Array[Variant] = [] for rec in _items: @@ -54,13 +54,13 @@ func inventory_count() -> int: # 持有数(同调位上限判定读数:只计未消耗件;Used 不可逆即不再持有) # 同调位守卫谓词(读取源 transitional_sync_slots 过渡键已随表退役; -# 容量闸正主 = 营地装配面 Attunement.slots 满位禁选。函数体保留空壳防四散引用误删遗漏—— +# 容量闸现行事实源 = 营地装配面 Attunement.slots 满位禁选。函数体保留空壳防四散引用误删遗漏—— # 冒烟「过渡键读取点归零」断言覆盖) # 持有件记录(奖励节点替换子交互数据源:只列未消耗件,handle 定位丢弃目标) # 丢弃(同调位替换交互节点渠道——腾位收新;与 Used 消费分轨的一次性移除,快照不再含) -# 板级零信息可用性预判(图标置灰/入口禁用判据——GDD「整张图都没东西可看」级): +# 整图零信息可用性预判(图标置灰/入口禁用判据——GDD「整张图都没东西可看」级): # 真视恒可用(零雷窗口=信息非空);AP 类恒可用(组合判据取 OR——任一效果有信息即可用); # 纯预读行 = 板上还有未开格才可用。(积点件不入使用面——自动兑付无玩家入口) func _usable_now(item_id: String, board_has_preview_info: Callable) -> bool: diff --git a/game/data/schemas/adventure_table.gd b/game/data/schemas/adventure_table.gd index 68e8f0bd..3bb3bcaf 100644 --- a/game/data/schemas/adventure_table.gd +++ b/game/data/schemas/adventure_table.gd @@ -89,12 +89,12 @@ const TIER_QUOTAS := {"common": 70, "excellent": 25, "rare": 7, "legendary": 0} @export var curio_cap_rap: int = 99 # [1,99] @export var curio_cap_time_sand: int = 99 # [1,99] -# —— 专长获取门票(非 Boss 渠道的专长入口形态,奇物.md v2.7 渠道轴定位; +# —— 专长获取专长凭证(非 Boss 渠道的专长入口形态,奇物.md v2.7 渠道轴定位; # 四口径契约④:拿到即开不可囤积/罕见只在概率不在价格/一局限购一次/计步保底连续 5 展示未出 # 第 6 必出(计数=展示次数、刷新重展计入、节点与商店共享、触发清零、限购满不再触发)。 # 四参数全部 provisional 归曲线调参;limit/pity_step 系口径定死值,调参可复议)—— -@export var feat_ticket_chance: int = 20 # [0,100] knob(provisional)——每次非 Boss 渠道展示门票出现概率 % -@export var feat_ticket_quota: int = 2 # [0,9] knob(provisional)——每局门票出现次数上限 +@export var feat_ticket_chance: int = 20 # [0,100] knob(provisional)——每次非 Boss 渠道展示专长凭证出现概率 % +@export var feat_ticket_quota: int = 2 # [0,9] knob(provisional)——每局专长凭证出现次数上限 @export var feat_ticket_limit: int = 1 # [1,9] knob(口径定死=1)——一局限购(选中/买下)次数 @export var feat_ticket_pity_step: int = 5 # [1,99] knob(口径定死=5)——保底步数(连续未出展示次数) diff --git a/game/data/schemas/settlement_table.gd b/game/data/schemas/settlement_table.gd index 96c80217..52191dea 100644 --- a/game/data/schemas/settlement_table.gd +++ b/game/data/schemas/settlement_table.gd @@ -5,7 +5,7 @@ class_name SettlementTable extends Resource @export var equivalence_ref_damage: int = 12 # [1,999] knob——当量参考敞口 D_ref -@export var p_perfect: int = 200 # {100,200} percent——完美排雷第二份兑付触发(载体域) +@export var p_perfect: int = 200 # {100,200} percent——完美封印第二份兑付触发(载体域) @export var seal_hit_premium: int = 100 # [100,999] percent knob——封印命中兑付溢价 ×(1+(n−100)/100):125=×1.25(条款3 条件二封印溢价形态 a,provisional);100=无溢价直通零扰动。只乘封印命中正向兑付(flat power/percent 幅度/gp 缓冲三形态),标空/挖格/清图不乘;雷安同池冻结不动 @export var segment_order: PackedStringArray = [] # 结构冻结——段序恒等校验违例致命 @export var source_label_map: Dictionary[String, Variant] = {} # 结构冻结——source_class→文案键 diff --git a/game/data/schemas/shop_table.gd b/game/data/schemas/shop_table.gd index ef07d5b1..4868d8da 100644 --- a/game/data/schemas/shop_table.gd +++ b/game/data/schemas/shop_table.gd @@ -15,7 +15,7 @@ extends Resource const GP_TIERS := ["normal", "elite", "boss"] const PRODUCT_ATTRS := ["atk", "max_hp", "armor_class"] -const SHELF_KINDS := ["attack", "max_hp", "armor", "ap", "feat_ticket", "heal"] # 货架候选词表(四切边后种 + 门票行 + heal 补回复〔默认原则:分类内成员都入该渠道池〕) +const SHELF_KINDS := ["attack", "max_hp", "armor", "ap", "feat_ticket", "heal"] # 货架候选词表(四切边后种 + 专长凭证行 + heal 补回复〔默认原则:分类内成员都入该渠道池〕) func validate() -> Array: diff --git a/game/data/schemas/variation_table.gd b/game/data/schemas/variation_table.gd index b88bd5da..65c4c7b6 100644 --- a/game/data/schemas/variation_table.gd +++ b/game/data/schemas/variation_table.gd @@ -17,7 +17,7 @@ const SCOPES := ["region", "global"] # resource_face = 资源面偏斜(全局作用域变异——整图修摇号分布:生存族按 effect_value% # 下调、进攻族等比上浮重归一,不动任何格子数据;effect_value 语义随行域切换,不适用 flat_damage [1,9]) const EFFECTS := ["none", "flat_damage", "hide_number", "resource_face"] # 效果词表:直伤 / 数字遮蔽 / 资源面偏斜(可扩充) -const TRIGGERS := ["on_open", "on_number_shown", "always"] # 触发词表:被打开即触发 / 打开且显示数字时触发 / 板级恒在无触发时机(可扩充) +const TRIGGERS := ["on_open", "on_number_shown", "always"] # 触发词表:被打开即触发 / 打开且显示数字时触发 / 整图恒在无触发时机(可扩充) const PLACEMENTS := ["closed_only", "any"] # 布置约束词表:只落布置时未开格 / 任意格(可扩充) @@ -76,7 +76,7 @@ func validate() -> Array: if row.get("placement", "") != "any": errs.append({"category": "cross_field", "message": "%s scope=global ⇒ placement 必为 any(整图无格子布置域)" % vid}) if row.get("trigger", "") != "always": - errs.append({"category": "cross_field", "message": "%s scope=global ⇒ trigger 必为 always(板级恒在,无触发时机)" % vid}) + errs.append({"category": "cross_field", "message": "%s scope=global ⇒ trigger 必为 always(整图恒在,无触发时机)" % vid}) return errs diff --git a/game/data/tables/shop.tres b/game/data/tables/shop.tres index 52e0fa16..f5af6c56 100644 --- a/game/data/tables/shop.tres +++ b/game/data/tables/shop.tres @@ -101,7 +101,7 @@ price_b = 1.1 ; (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 渠道专长入口,价与其他商品相当=契约④口径②〕、 +; 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 行族 + 加法定价 diff --git a/game/presentation/curio_interact_controller.gd b/game/presentation/curio_interact_controller.gd index f40874d3..25710a56 100644 --- a/game/presentation/curio_interact_controller.gd +++ b/game/presentation/curio_interact_controller.gd @@ -86,7 +86,7 @@ func _skip_empty_stop() -> bool: # 增量行在其上),确认后进三选一面(level-clear.md v2);续玩停点恢复同入口(零自动推进契约) func on_presented(payload: Dictionary) -> void: if String(payload.get("context", "")) == "feat_ticket": - # T5 店内门票兑付——临时停点开专长三选一面(零胜利总结面;确认后只关面回店) + # T5 店内专长凭证兑付——临时停点开专长三选一面(零胜利总结面;确认后只关面回店) _pending_curio = payload.duplicate(true) _curio_context = "feat_ticket" if (_pending_curio.get("candidates", []) as Array).is_empty(): @@ -214,7 +214,7 @@ func on_pick_confirmed(item_id: String) -> void: if not ok: push_error("[bonus_interact] 三选一兑付被拒——见输出日志") return - # T5——节点渠道门票拿到即开:候选已被替换为专长面,本地读在途态重绘(零 emit——context 保持 reward_node, + # T5——节点渠道专长凭证拿到即开:候选已被替换为专长面,本地读在途态重绘(零 emit——context 保持 reward_node, # 后续兑付/确认仍走节点路径回图选路) if _curio_context == "reward_node" and kind == "feat_ticket": var st2: Dictionary[Variant, Variant] = adventure.node_curio_pending_state() @@ -234,7 +234,7 @@ func on_continue() -> void: curio_overlay.close_pick() var adventure = _adventure_get.call() if _curio_context == "feat_ticket": - return # T5 店内门票面——专长兑付完成后关面回店(无推进/无回图) + return # T5 店内专长凭证面——专长兑付完成后关面回店(无推进/无回图) if _curio_context == "reward_node": var runner = _runner_get.call() if runner != null: diff --git a/game/presentation/hud_presenter.gd b/game/presentation/hud_presenter.gd index 0ead2a5b..2ce1214f 100644 --- a/game/presentation/hud_presenter.gd +++ b/game/presentation/hud_presenter.gd @@ -37,7 +37,7 @@ static func refresh(stage: BattleStageView, info: HeroInfoPanelView, ap_bar: ApB _refresh_out_of_battle(stage, info, ap_bar, runner, level_active, db) return var s: Dictionary[Variant, Variant] = settlement.presentation_snapshot() - # 地形变异常驻角标投影(板级变异快照 → 文案行; + # 地形变异常驻角标投影(整图变异快照 → 文案行; # 空态隐藏=特性段先例;战斗全程常驻防中局遗忘) info.set_board_variants(board_variant_lines(db, s.get("board_variants", []))) var hero: Dictionary[Variant, Variant] = s.hero @@ -102,7 +102,7 @@ static func feat_holdings_lines(db, held: Array) -> Array[String]: return rlines -# 地形变异常驻角标文案(板级变异 id → 文案行; +# 地形变异常驻角标文案(整图变异 id → 文案行; # 空集 = 空数组=空态隐藏。三行制:变异名+两行效果说明(C 区 240px 宽防裁切)。 # 文案用常规表述,不用俚语 static func board_variant_lines(db, ids: Array) -> Array[String]: diff --git a/game/presentation/main.gd b/game/presentation/main.gd index c8fe9a97..42bcc882 100644 --- a/game/presentation/main.gd +++ b/game/presentation/main.gd @@ -911,7 +911,7 @@ func _on_round_started(ri: int) -> void: # 巢穴预告呈现(装板报数量读数口消费:≥0=本战装配命中,toast 一次性提示) if run_scope.settlement != null and int(run_scope.settlement.nest_preview_count) >= 0: board_zone.toast.show_toast("巢穴预告——本板危险格共 %d 个" % int(run_scope.settlement.nest_preview_count), "info") - # 开战横幅——板级地形变异预告:首轮快照 board_variants + # 开战横幅——整图地形变异预告:首轮快照 board_variants # 非空才发射(Boss 图恒带一型=替换制;普通图空快照零发射);轮横幅下方叠行,view 内判减动效。 if ri == 1 and run_scope.settlement != null: var bvs: Array[Variant] = run_scope.settlement.presentation_snapshot().get("board_variants", []) diff --git a/game/presentation/row_pacer.gd b/game/presentation/row_pacer.gd index d5ca6037..fb70ea59 100644 --- a/game/presentation/row_pacer.gd +++ b/game/presentation/row_pacer.gd @@ -89,7 +89,7 @@ func _consume_row(row: Dictionary) -> void: stage.on_step_row_fx(row) _play_cross_zone_fx(row) # 跨区因果演出(结算演出链批):开格之因 → 站桩之果 _play_settlement_mark(row) # 三轮 #3——逐条标出:Buff/Debuff 色环脉冲 → 伤害/治疗数字浮现 - # 高光演出(战斗结算×3①② 占位):完美排雷横幅 / 封印命中加重弹道 + # 高光演出(战斗结算×3①② 占位):完美封印横幅 / 封印命中加重弹道 if String(row.get("type", "")) == "highlight" and String(row.get("highlight", "")) != "skill_unlock": board_zone.fx.play_perfect_sweep() elif String(row.get("highlight", "")) == "seal_hit": diff --git a/game/presentation/treasure_interact_controller.gd b/game/presentation/treasure_interact_controller.gd index cafc6cc4..2c3084b8 100644 --- a/game/presentation/treasure_interact_controller.gd +++ b/game/presentation/treasure_interact_controller.gd @@ -98,7 +98,7 @@ func attempt_use(handle: int, cell: Variant = null) -> void: toast.show_toast("已使用 %s" % String(arow.get("display_name", "")), "info") -# 库存投影(C 区四槽取数面——字形=名首字;usable=板级零信息预判回调接排雷玩法只读面) +# 库存投影(C 区四槽取数面——字形=名首字;usable=整图零信息预判回调接排雷玩法只读面) func inventory_projection() -> Array: var runner = _runner_get.call() if runner == null or runner.treasure_inventory == null: diff --git a/game/presentation/views/battle_log_view.gd b/game/presentation/views/battle_log_view.gd index 446126d4..11c7fa04 100644 --- a/game/presentation/views/battle_log_view.gd +++ b/game/presentation/views/battle_log_view.gd @@ -189,7 +189,7 @@ func _format_row(row: Dictionary, agg_count := -1) -> String: var n := (" ×%d" % agg_count) if agg_count > 1 else "" return prefix + "[s][color=#%s]⚠ %s%s[/color][/s]%s" % [UiKit.HEX_LOG_VOIDED, name_, n, suffix] "seal_miss": - var body := "✗ %s%s" % [name_, "(本板完美排雷已破——归因此封印)" if hl == "perfect_broken" else ""] + var body := "✗ %s%s" % [name_, "(本板完美封印已破——归因此封印)" if hl == "perfect_broken" else ""] return prefix + (_gold_frame(body) if hl == "perfect_broken" else "[color=#%s]%s[/color]" % [UiKit.HEX_LOG_ROUND, body]) "cast": # 施放行:增益技 0 伤害施放,具名技能 diff --git a/game/presentation/views/board_cell_unit.gd b/game/presentation/views/board_cell_unit.gd index a704d60a..31d1ac24 100644 --- a/game/presentation/views/board_cell_unit.gd +++ b/game/presentation/views/board_cell_unit.gd @@ -94,7 +94,7 @@ var facade_strip := false: # E 格开关(BoardView paint 按「已开 # 变异角标(程序化,tex_mutation 纹带槽暂留): # "flat_damage" = 未开格伤害型变异,左下角危险红三角(开格有代价的策略纹理标记) -# 叠加层标记(秘宝板级叠加层的格面呈现;派生信息层零回写): +# 叠加层标记(秘宝整图叠加层的格面呈现;派生信息层零回写): # "mine_reveal" = 真视格(危险红内缩框——「这格是雷」的确定决策标记,封印照常计费); # "reward_preview" 格不复用本字段——预读徽章走 badge_glyph 注入(board_view refresh 注入 REWARD_BADGE 字形) var treasure_mark := "": @@ -108,8 +108,8 @@ var mutation_mark := "": mutation_mark = v queue_redraw() -# ── 视野迷雾呈现态(纯呈现零逻辑;规格=art-bible §6.5 v3.5,正主=HUD框架「视野迷雾」节)── -# 0=正常(灯光区内)/ 1=全黑(区外未开格——正主「区外未开格=全黑不渲染」不透明档)/ 2=记忆态(区外已开格灰显可读) +# ── 视野迷雾呈现态(纯呈现零逻辑;规格=art-bible §6.5 v3.5,现行事实源=HUD框架「视野迷雾」节)── +# 0=正常(灯光区内)/ 1=全黑(区外未开格——现行事实源「区外未开格=全黑不渲染」不透明档)/ 2=记忆态(区外已开格灰显可读) var fog_state := 0: set(v): if fog_state != v: diff --git a/game/presentation/views/board_fx_view.gd b/game/presentation/views/board_fx_view.gd index 0013ec8a..5fc47c7a 100644 --- a/game/presentation/views/board_fx_view.gd +++ b/game/presentation/views/board_fx_view.gd @@ -1,5 +1,5 @@ ## VERTICAL SLICE - NOT FOR PRODUCTION -## D 区演出层:清图喷泉/Boss 影子/完美排雷光带/封印命中弹道/挥铲三帧等一次性占位演出。 +## D 区演出层:清图喷泉/Boss 影子/完美封印光带/封印命中弹道/挥铲三帧等一次性占位演出。 ## 组合根按核心信号直调 play_*;素材缺位静默回退(演出层不设断言面)。 class_name BoardFxView extends Control @@ -87,7 +87,7 @@ func play_boss_shadow() -> void: tw.tween_callback(shadow.queue_free) -# 完美排雷:金光带加倍扫射 + 横幅占位(§2.2 最高档) +# 完美封印:金光带加倍扫射 + 横幅占位(§2.2 最高档) func play_perfect_sweep() -> void: for i in 2: var band := ColorRect.new() @@ -99,7 +99,7 @@ func play_perfect_sweep() -> void: var tw := band.create_tween() tw.tween_property(band, "position:x", size.x + 8.0, UiKit.motion(0.5 + 0.15 * i)) tw.tween_callback(band.queue_free) - _show_banner("完美排雷 ×2") + _show_banner("完美封印 ×2") # 封印命中:封印化暴击弹道加重占位(自棋盘上缘飞向 B 区敌人卡方向——越界即收) diff --git a/game/presentation/views/board_view.gd b/game/presentation/views/board_view.gd index 72835d61..88e2d230 100644 --- a/game/presentation/views/board_view.gd +++ b/game/presentation/views/board_view.gd @@ -117,7 +117,7 @@ var _digit_dark_ink := true # 数字墨族按板自适应(true=深墨 var _digit_plate := false # 数字色牌垫底模式(双峰纹理板——直画两族皆不过门槛时落牌, # 素牌+深墨 12:1 纹理免疫;渲染帧取证 underdark 系深墨直画隐形,故启用色牌) -# ---- 视野迷雾(纯呈现层;正主=HUD框架「视野迷雾」节 v0.13,渲染规格=art-bible §6.5 v3.5)---- +# ---- 视野迷雾(纯呈现层;现行事实源=HUD框架「视野迷雾」节 v0.13,渲染规格=art-bible §6.5 v3.5)---- const FOG_RADIUS := 8 # 菱形灯光区基准半径(曼哈顿距离 ≤R——与微光环「周围 8 格」同圈起步;半径基准值改动=非白名单须用户) var _fog_enabled := true # 迷雾开关(呈现态布尔——真实游戏恒 on;探针/夹具可 off=无迷雾基线,两态结算逐位一致断言面) var _fog_lantern := 0 # 视野加成现值(缺省 0=无加成基线零扰动;生产写入面=组合根每战装配链显式重算——main._sync_treasure_glow) @@ -142,7 +142,7 @@ func _init() -> void: add_child(_wrap) _svp_container = SubViewportContainer.new() _svp_container.stretch = true # 容器尺寸 = 视口逻辑分辨率(_update_world_size 同步)——恒 1:1 无缩放 - _svp_container.mouse_filter = Control.MOUSE_FILTER_IGNORE # 输入归壳层 _gui_input(板级公式换算),不进 SubViewport + _svp_container.mouse_filter = Control.MOUSE_FILTER_IGNORE # 输入归壳层 _gui_input(整图公式换算),不进 SubViewport _wrap.add_child(_svp_container) _viewport = SubViewport.new() _viewport.transparent_bg = true # 格间距露出 D 区底色 @@ -502,7 +502,7 @@ func click_cell(cell: Vector2i, button: int) -> void: _on_cell_input(cell, ev) -# 板级公式单点:格坐标 = floor(板内局部坐标 / 格步长) +# 整图公式单点:格坐标 = floor(板内局部坐标 / 格步长) #(格步长 = 格边长 + 间距;板外/负域返回 (-9,-9);2px 格间隙落入左/上邻格) func _cell_at(shell_pos: Vector2) -> Vector2i: if _board == null or _board.width == 0: @@ -534,7 +534,7 @@ func _update_world_size() -> void: _viewport.size = px -# 真实输入路径(Node2D 迁移批 Decision 3):壳层 _gui_input → 板级公式换算 → 复用既有 hover/点选/chord 出口 +# 真实输入路径(Node2D 迁移批 Decision 3):壳层 _gui_input → 整图公式换算 → 复用既有 hover/点选/chord 出口 func _gui_input(ev: InputEvent) -> void: if _minesweeper == null: return @@ -832,7 +832,7 @@ func _paint_cell(c: Vector2i, hero: Vector2i) -> void: u.mutation_mark = "" u.badge_glyph = _update_badge(c) u.glow_group = int(_glow.get(c, UiKit.GLOW_NONE)) - # 视野迷雾呈态:曼哈顿距离 > 半径 → 区外——未开格全黑(正主照抄)/ + # 视野迷雾呈态:曼哈顿距离 > 半径 → 区外——未开格全黑(现行事实源照抄)/ # 已开格记忆态(灰显可读);以英雄格为心逐格重算,refresh()/notify_hero_move() 既有重绘驱动=移动实时跟随。 # 纯呈现零逻辑——格态/数字真值/清图判定零触碰(🔴 契约 1);结算期去饱和叠加互斥由 CellUnit 记忆态终态档承载。 if _fog_enabled: diff --git a/game/presentation/views/curio_pick_overlay.gd b/game/presentation/views/curio_pick_overlay.gd index 6e3cd430..13dd1c91 100644 --- a/game/presentation/views/curio_pick_overlay.gd +++ b/game/presentation/views/curio_pick_overlay.gd @@ -107,7 +107,7 @@ func open_pick(header: String, cards: Array) -> void: _confirm_btn.visible = false _continue_btn.visible = false _foot_hint.visible = true # T7 底注=pick 态专属(result 态让位) - _refresh_btn.visible = false # 刷新面随 set_refresh_display 投喂后现形(open 先归零防残留;店内门票面不投喂=无刷新) + _refresh_btn.visible = false # 刷新面随 set_refresh_display 投喂后现形(open 先归零防残留;店内专长凭证面不投喂=无刷新) _refresh_l.text = "" visible = true diff --git a/game/presentation/views/hero_info_panel_view.gd b/game/presentation/views/hero_info_panel_view.gd index d94c7139..a7465d05 100644 --- a/game/presentation/views/hero_info_panel_view.gd +++ b/game/presentation/views/hero_info_panel_view.gd @@ -117,7 +117,7 @@ func set_feat_holdings(lines: Array) -> void: _feat_section.visible = not lines.is_empty() -# 地形变异常驻角标:lines = 文案行(板级变异 display_name+体感短语)——空数组 = 整节隐藏 +# 地形变异常驻角标:lines = 文案行(整图变异 display_name+体感短语)——空数组 = 整节隐藏 func set_board_variants(lines: Array) -> void: for c3 in _board_variant_list.get_children(): _board_variant_list.remove_child(c3) @@ -157,7 +157,7 @@ func _data_line() -> Label: # ---- 秘宝库存条(C 区四槽常读+两步交互第一步)---- # 投影行 = {handle, glyph, name, used, usable}(组合根组装:字形=道具名首字;数据源 runner 级库存只读面)。 -# 空槽=虚位;used=暗态「已用」保留占位(Used 不可逆——受理序展示语义);不可用=置灰(板级零信息); +# 空槽=虚位;used=暗态「已用」保留占位(Used 不可逆——受理序展示语义);不可用=置灰(整图零信息); # selected=金框高亮(两步交互第一步的可见态)。tooltip=全名+维度语义。 func set_treasure_inventory(items: Array, selected_handle: int) -> void: _selected_handle = selected_handle diff --git a/game/presentation/views/settlement_fx_view.gd b/game/presentation/views/settlement_fx_view.gd index 5881d2ba..6f02d2b3 100644 --- a/game/presentation/views/settlement_fx_view.gd +++ b/game/presentation/views/settlement_fx_view.gd @@ -11,7 +11,7 @@ func _init() -> void: # 结算轮光带:金橙半透明横带自棋盘上缘扫至下缘(一次 0.5s,自动回收)—— -# "棋盘能量向战斗画面汇聚"的开轮语义(§2.2 色彩转金橙主导;区分于 board_fx 的完美排雷金光带)。 +# "棋盘能量向战斗画面汇聚"的开轮语义(§2.2 色彩转金橙主导;区分于 board_fx 的完美封印金光带)。 # 终稿(样张 v2 冻结批 T3):加 2px 亮金前导缘线——扫带运动方向可读(兑现光带逐行横扫 §2.2) func play_round_sweep(board_rect: Rect2) -> void: if board_rect.size == Vector2.ZERO: @@ -143,7 +143,7 @@ func play_round_banner(ri: int) -> void: tw.tween_callback(banner.queue_free) -# 开战横幅——板级地形变异预告:board_variants 非空时开战 +# 开战横幅——整图地形变异预告:board_variants 非空时开战 # 显示一行(文本=「地形变异 · 贫矿脉」式);减动效=静态驻留后即隐(轮横幅先例——行呈现不跳过)。 # 文案/驻留参数 provisional 归本地化批;普通图恒不发射(组合根按快照 board_variants 空判)。 func play_board_variant_banner(text: String) -> void: diff --git a/game/smoke/board_shot_probe.gd b/game/smoke/board_shot_probe.gd index 3c0688a6..0080a3f4 100644 --- a/game/smoke/board_shot_probe.gd +++ b/game/smoke/board_shot_probe.gd @@ -28,7 +28,7 @@ var _cur_settlement = null # 当关 settlement(身份回调读取面—— func _ready() -> void: # 运行前提=窗口化真渲染面(shot_probe 同款护栏——headless 下 frame_post_draw 永不触发+视口纹理恒空) if DisplayServer.get_name() == "headless": - print("[board_shot] FAIL — 本探针必须窗口化运行(headless 无渲染面,截图必空);正主=tools/render_gate.sh 取证段") + print("[board_shot] FAIL — 本探针必须窗口化运行(headless 无渲染面,截图必空);现行事实源=tools/render_gate.sh 取证段") get_tree().quit(1) return var args := OS.get_cmdline_user_args() diff --git a/game/smoke/layout_probe.gd b/game/smoke/layout_probe.gd index a87e0665..f354b53f 100644 --- a/game/smoke/layout_probe.gd +++ b/game/smoke/layout_probe.gd @@ -1,5 +1,5 @@ # VERTICAL SLICE - NOT FOR PRODUCTION -# 布局几何断言探针(正主=tools/probe_gate.sh 默认段;呈现层三区布局的分辨率维度验收) +# 布局几何断言探针(现行事实源=tools/probe_gate.sh 默认段;呈现层三区布局的分辨率维度验收) # 用途:battle.md §验收「1280×800 与 16:9 全屏下三区无遮挡/无重叠/无裁切」的可执行化 # GDD 锚:design/gdd/ux/battle.md §Layout Zones(B/C/D 三区几何) # 硬约束:档位表是数据、断言是一份函数据——加档只改表不动断言(禁每档建一个探针) diff --git a/game/smoke/level_autoplay.gd b/game/smoke/level_autoplay.gd index 01db2653..4834acc2 100644 --- a/game/smoke/level_autoplay.gd +++ b/game/smoke/level_autoplay.gd @@ -222,7 +222,7 @@ static func _on_adventure_node_entered(node: Dictionary, info: Dictionary, adr, adr.present_node_curio(ncands) var npick: Dictionary = _pick_token(ncands, String(st.get("feat_mode", "off"))) if adr.apply_node_curio(String(npick.get("kind", "")), String(npick.get("tier", "")), String(npick.get("feat_id", ""))): - # 门票拿到即开——候选已被替换为专长三选一,就地再选一轮(确定性策略同款 316-f); + # 专长凭证拿到即开——候选已被替换为专长三选一,就地再选一轮(确定性策略同款 316-f); # 不作此分支则节点停点悬空→选路卡死(MC timeout 形态) if String(npick.get("kind", "")) == "feat_ticket": var fcands: Array = (adr.node_curio_pending_state().get("candidates", []) as Array) diff --git a/game/smoke/shot_probe.gd b/game/smoke/shot_probe.gd index 09d6e3ab..8abd3cd8 100644 --- a/game/smoke/shot_probe.gd +++ b/game/smoke/shot_probe.gd @@ -1,6 +1,6 @@ # VERTICAL SLICE - NOT FOR PRODUCTION # 整屏截图探针(呈现层测试分级 B 档基建:视口截图程序化产出;七屏—— -# 菜单/设置面/生涯页/营地/关卡画面/战斗/状态面板,正主=tools/render_gate.sh)。 +# 菜单/设置面/生涯页/营地/关卡画面/战斗/状态面板,现行事实源=tools/render_gate.sh)。 # 必须**窗口化**运行(真渲染设备——headless 无渲染面,get_image 得到空纹理): # Godot_console.exe --path . res://smoke/shot_probe.tscn -- <输出目录> # 流程 = 真实按钮信号路径驱动(ui_click_probe 同款;存档/设置/元进度三面换注隔离档——禁碰真实档, @@ -25,7 +25,7 @@ var _meta := {} # 控件实测几何(全局 rect——shot_checker 文字框 func _ready() -> void: # 运行前提=窗口化真渲染面:headless 下 frame_post_draw 永不触发+视口纹理恒空——无此守卫时 headless 调用方必挂死 if DisplayServer.get_name() == "headless": - print("[shot_probe] FAIL — 本探针必须窗口化运行(headless 无渲染面,截图必空);headless 自动闸禁跑本探针(正主=tools/probe_gate.sh)") + print("[shot_probe] FAIL — 本探针必须窗口化运行(headless 无渲染面,截图必空);headless 自动闸禁跑本探针(现行事实源=tools/probe_gate.sh)") get_tree().quit(1) return var args := OS.get_cmdline_user_args() diff --git a/game/smoke/smoke_all.gd b/game/smoke/smoke_all.gd index 902d50d2..8f74b2aa 100644 --- a/game/smoke/smoke_all.gd +++ b/game/smoke/smoke_all.gd @@ -1357,15 +1357,15 @@ func _smoke_feats() -> void: if String((t as Dictionary).get("kind", "")) == "relic": node_relic_seen = true check(feat_seen.size() >= 2, "通关渠道只出专长(60 次重抽 ≥2 种不同 relic——身份键 feat_id 同档可多件)") - check(not node_relic_seen, "节点渠道零专长(60 次重抽零 relic——专长在非 Boss 渠道只以门票形态出现)") - # T5 门票行为断言(A5 拿到即开 / A6 保底计数——契约④四口径;独立 runner 防污染 a_r 牌库) + check(not node_relic_seen, "节点渠道零专长(60 次重抽零 relic——专长在非 Boss 渠道只以专长凭证形态出现)") + # T5 专长凭证行为断言(A5 拿到即开 / A6 保底计数——契约④四口径;独立 runner 防污染 a_r 牌库) var a_t = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(91)) a_t.start_adventure(91, {"first_script": true}) var stock_before := {} for kk in ["attack", "gp", "heal"]: stock_before[kk] = a_t.pool_stock(kk) a_t._node_curio_pending = {"candidates": [{"kind": "feat_ticket", "tier": "excellent"}, {"kind": "attack", "tier": "common"}]} - check(a_t.apply_node_curio("feat_ticket", "excellent"), "A5 门票兑付受理(节点渠道——拿到即开)") + check(a_t.apply_node_curio("feat_ticket", "excellent"), "A5 专长凭证兑付受理(节点渠道——拿到即开)") var tkt_cands: Array = (a_t.node_curio_pending_state().get("candidates", []) as Array) var tkt_all_relic := tkt_cands.size() > 0 for t in tkt_cands: @@ -1373,13 +1373,13 @@ func _smoke_feats() -> void: tkt_all_relic = false check(tkt_all_relic, "A5 拿到即开——停点候选已替换为专长三选一(全 relic)") check(a_t.pool_stock("attack") == int(stock_before["attack"]) and a_t.pool_stock("gp") == int(stock_before["gp"]), - "A5 零摘牌——门票兑付不动令牌库(不进持有集)") - check(not (a_t.feats_held() as Array).has("feat_ticket"), "A5 无门票残留持有集") + "A5 零摘牌——专长凭证兑付不动令牌库(不进持有集)") + check(not (a_t.feats_held() as Array).has("feat_ticket"), "A5 无专长凭证残留持有集") var feats_n := (a_t.feats_held() as Array).size() a_t.apply_node_curio("relic", String((tkt_cands[0] as Dictionary).get("tier", "rare")), String((tkt_cands[0] as Dictionary).get("feat_id", ""))) - check((a_t.feats_held() as Array).size() == feats_n + 1, "A5 专长面兑付受理(门票开出候选可正常入持有集)") + check((a_t.feats_held() as Array).size() == feats_n + 1, "A5 专长面兑付受理(专长凭证开出候选可正常入持有集)") # A6 保底:pity 直填 5 → 下次展示必出(第 6 次必出口径);限购满 → 恒不触发 - a_t._feat_ticket_sold = 0 # A5 已兑付一枚门票(sold=1=limit)——A6 段重置计数隔离验证 + a_t._feat_ticket_sold = 0 # A5 已兑付一枚专长凭证(sold=1=limit)——A6 段重置计数隔离验证 a_t._feat_ticket_pity = int(a_t.db.adventure.feat_ticket_pity_step) var rg_t: RandomNumberGenerator = a_t.rng.open_stream("reward_pick") check(a_t._feat_ticket_consider(rg_t), "A6 保底触发(pity=5 → 第 6 次展示必出——概率无关)") @@ -1841,7 +1841,7 @@ func _smoke_type_glow() -> void: check((snap.get("cells", {}) as Dictionary).size() == mapped - 1, "V2 清单外格剔除后作用集 = 派定数 −1(%d→%d)" % [mapped, (snap.get("cells", {}) as Dictionary).size()]) # ---- 相 3:封锁格(query 返回 null)⇒ 无微光且零登记 ---- - _glow_type_overrides.erase(bogus_cell) # 复位清单外(errors 保留=板级登记语义) + _glow_type_overrides.erase(bogus_cell) # 复位清单外(errors 保留=整图登记语义) var blocked_cell: Vector2i = hero for i in mini(assign.size(), nbs.size()): var nb4: Vector2i = nbs[i] @@ -2582,7 +2582,7 @@ func _smoke_global_variant() -> void: vt.rows.assign([{"variant_id": "g3", "display_name": "负丙", "unlock_level": 2, "scope": "global", "effect": "resource_face", "effect_value": 30, "trigger": "on_open", "placement": "any", "board_types": [], "counter_items": []}]) - check(_errs_has_cross_field(vt.validate()), "互锁负样本⑤:scope=global + trigger=on_open 被拒(global ⇒ always 板级恒在)") + check(_errs_has_cross_field(vt.validate()), "互锁负样本⑤:scope=global + trigger=on_open 被拒(global ⇒ always 整图恒在)") vt.rows.assign([{"variant_id": "g4", "display_name": "负丁", "unlock_level": 2, "scope": "global", "effect": "resource_face", "effect_value": 30, "trigger": "always", "placement": "closed_only", "board_types": [], "counter_items": []}]) @@ -2624,7 +2624,7 @@ func _smoke_global_variant() -> void: var boss1_calls := 0 if boss_ok: var bb = boss_settlement.minesweeper.current_board() - check(bb.board_variant_ids().is_empty(), "屏蔽后回落:Boss 图无板级全局型(board_variants 空——全局池空合法态)") + check(bb.board_variant_ids().is_empty(), "屏蔽后回落:Boss 图无整图全局型(board_variants 空——全局池空合法态)") var boss_vids := {} for vc in bb.variants: for vid in bb.variants[vc]: @@ -3497,7 +3497,7 @@ func _encounter_replay(seed_val: int) -> Array: # ==================== 清图奖励双份兑付链 / 轮内刷新 provenance 守卫 / 窗口锚行 ==================== -# 清图 = 全安全格开完。清图测试用"真雷封印(零误标→完美排雷)+ AutoPlayer 逐轮清图"真实流驱动; +# 清图 = 全安全格开完。清图测试用"真雷封印(零误标→完美封印)+ AutoPlayer 逐轮清图"真实流驱动; # DifficultyTable 注入 hp_mult=10 把 Boss 血量抬到 1500,保证清图批次发生在战斗结束之前(测试台账,跑完即还原)。 const CLEAR_SMOKE_DEPTH := 4 @@ -3506,11 +3506,11 @@ var _regular_clear_reward_rows := 0 # 常规(非刷新图)清图的 clear_ func _smoke_clear_reward_chain() -> void: - print("--- 清图奖励·双份兑付链(完美排雷 / 零兑付 / 第二份被拒 / 高光记实)---") - # ① 真实流完美排雷:标中一面真雷封印 + 零误标 + 清全图 → grant_clear 身份(clear_blast)双份真实兑付 + print("--- 清图奖励·双份兑付链(完美封印 / 零兑付 / 第二份被拒 / 高光记实)---") + # ① 真实流完美封印:标中一面真雷封印 + 零误标 + 清全图 → grant_clear 身份(clear_blast)双份真实兑付 var rows: Array = [] var run := _run_full_clear(20260915, false, rows) - check(bool(run.cleared), "① 完美排雷清图达成(%d 轮)" % int(run.rounds)) + check(bool(run.cleared), "① 完美封印清图达成(%d 轮)" % int(run.rounds)) var dmg := [] for r in rows: if String(r.get("type", "")) == "damage" and String(r.get("source_class", "")) == "clear_reward": @@ -4070,7 +4070,7 @@ func _drive_clear(settlement) -> Dictionary: if t.hero_cell != ms.hero_pos(): ms.settle_batch([{"action": "move", "cell": t.hero_cell}]) ms.settle_batch([{"action": "seal_place", "cell": t.seal_cell}]) - seal_done = true # 一面真雷封印 = 完美排雷前半(零误标),后半靠 AutoPlayer 清图 + seal_done = true # 一面真雷封印 = 完美封印前半(零误标),后半靠 AutoPlayer 清图 var seq_before: int = int(settlement.diagnostic_snapshot().board_seq) var out := {"result": "", "rounds": 0, "terminated": false, "stream": []} _auto_play_round(settlement, out) @@ -5298,7 +5298,7 @@ func _smoke_shop_pool() -> void: # ⑧ 终局池读数(run_adventure pool 面——商店与奖励跨渠道消耗后的终局余量出讫) var st_pool: Dictionary = autoplay.run_adventure(_db, 42, 0, 0, false, null, "normal", "min", {}, {}, {"mode": "pool"}) var ps: Dictionary = st_pool.get("pool_stock", {}) - check(ps.size() == 6, "终局池读数六键出讫(run_adventure pool 面——四池种+T5 门票+T6 heal 行,读数只锚一次载体)") + check(ps.size() == 6, "终局池读数六键出讫(run_adventure pool 面——四池种+T5 专长凭证+T6 heal 行,读数只锚一次载体)") var ps_ok := true for k in ps.keys(): var quota := 0 @@ -6191,7 +6191,7 @@ func _smoke_battle_log_view() -> void: "cast": {"type": "cast", "display_name": "卓尔精灵 施放 毒雾", "source_class": "enemy_action", "round_index": 3}, "decay": {"type": "decay", "value": 1, "round_index": 3}, "verdict": {"type": "verdict", "display_name": "下一轮次", "value": 0, "round_index": 3}, - "highlight": {"type": "highlight", "display_name": "完美排雷!清图奖励 ×2", "value": 2, "source_class": "clear_reward", "round_index": 4}, + "highlight": {"type": "highlight", "display_name": "完美封印!清图奖励 ×2", "value": 2, "source_class": "clear_reward", "round_index": 4}, } for row_type in rest: var before: int = view.parsed_text().length() diff --git a/game/smoke/t17_defer_probe.gd b/game/smoke/t17_defer_probe.gd index efbb2ae0..96ff1383 100644 --- a/game/smoke/t17_defer_probe.gd +++ b/game/smoke/t17_defer_probe.gd @@ -3,7 +3,7 @@ # 真实信号路径驱动一场战斗到击杀胜利(结算行在排播队列),断言两条: # ①胜利同帧:终局面未开 + 挂起态在案 + 队列非空(旧行为=同帧 flush+开窗,本断言即红——判别性); # ②排播放完:终局面开启(演播完边沿派发——_on_pump_ended)。 -# 存档/设置/元进度三面隔离(isolate_save 正主,meta 经 autoload 链同源),零真实档触碰。headless 可跑(不抓帧)。 +# 存档/设置/元进度三面隔离(isolate_save 现行事实源,meta 经 autoload 链同源),零真实档触碰。headless 可跑(不抓帧)。 extends Node const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd") # 隔离样板单点 @@ -17,7 +17,7 @@ func _ready() -> void: main = load("res://presentation/main.tscn").instantiate() add_child(main) await get_tree().process_frame - # 存档/设置两面隔离(ProbeUiUtil.isolate_save 正主,先删后建防陈旧档泄入)—— + # 存档/设置两面隔离(ProbeUiUtil.isolate_save 现行事实源,先删后建防陈旧档泄入)—— # 隔离面走 attach_path 原地重置 autoload 单例:组合根 save_manager/meta 是getter-only # 读视图,直接赋值无效,隔离必须落在单例上。 ProbeUiUtil.isolate_save(main, "t17_defer_probe", false, true, false) diff --git a/game/smoke/ui_input_probe.gd b/game/smoke/ui_input_probe.gd index 2c4fc76a..a12d8246 100644 --- a/game/smoke/ui_input_probe.gd +++ b/game/smoke/ui_input_probe.gd @@ -1,7 +1,7 @@ # VERTICAL SLICE - NOT FOR PRODUCTION # push_input 端到端输入探针(场景结构登记项转义务 + Node2D 呈现层 Risks 缓解面)。 # 现役探针全走 BoardView.click_cell 直调(合成鼠标事件零命中已实证)—— -# 本探针是真实输入路径的唯一自动化覆盖:鼠标事件 → 壳层 _gui_input → 板级公式换算(_cell_at)→ +# 本探针是真实输入路径的唯一自动化覆盖:鼠标事件 → 壳层 _gui_input → 整图公式换算(_cell_at)→ # 悬停/点选/chord 既有出口 → 组合根信号。四 case:①悬停可挖域(金框+十字光标)②悬停禁入 # (hover_forbidden 信号+灰禁红框)③悬停已开格(路径预览点迹+移动光标)④右键封印(seal_place # 到达组合根+核心封印态)⑤双击 chord(禁入格双左击,核心拒挖零副作用)⑥左键挖(dig 到达组合根+核心揭格) diff --git a/game/tests/README.md b/game/tests/README.md index 4d2cf913..b91827bc 100644 --- a/game/tests/README.md +++ b/game/tests/README.md @@ -112,7 +112,7 @@ timeout 120s godot --headless --script tests/run_all.gd `tests/static_scan.sh` 实现静态扫描域 S1–S11 的可执行子集;规则全集与动机见 `design/engineering/architecture/architecture.md`「测试与质量域」节。新违规案例必须**先补扫描规则再修码**。 -S11 代码注释禁用词:扫描 game/ 全域 .gd/.tres/.md/.json/.sh 的注释面,词表从 `design/gdd/术语表.md`「退役词对照」解析(显式追加「完美排雷」,排除「巢穴」「旗」);三层豁免(闸门自指/显式留档 4 处/非注释面天然不取);两道自检(扫描面文件数非空+词表解析非空)。 +S11 代码注释禁用词:扫描 game/ 全域 .gd/.tres/.md/.json/.sh 的注释面,词表从 `design/gdd/术语表.md`「退役词对照」解析(显式追加「完美封印」,排除「巢穴」「旗」);三层豁免(闸门自指/显式留档 4 处/非注释面天然不取);两道自检(扫描面文件数非空+词表解析非空)。 ## 本地闸(唯一验收门禁) diff --git a/game/tests/smoke/critical-paths.md b/game/tests/smoke/critical-paths.md index af01c964..fcca9db1 100644 --- a/game/tests/smoke/critical-paths.md +++ b/game/tests/smoke/critical-paths.md @@ -17,7 +17,7 @@ 5. 移动:已开格瞬移、**已引爆危险格可通行可读**(工程债呈现半边) 6. 停手:RAP 1:1 转存、下轮 AP 硬重置同图继续 7. 轮末结算:明细逐行呈现、来源标注可读(P2——"这一行是我哪步扫雷带来的"可答) -8. 清图:清图奖励兑付 + 完美排雷高光(零误标时双份)+ 换新图;未刷新的停手轮不换图 +8. 清图:清图奖励兑付 + 完美封印高光(零误标时双份)+ 换新图;未刷新的停手轮不换图 9. 轮内刷新(方案 A):Active 当场换图、AP 保留、RAP 扣减、每轮 ≤2 次、跨图事实结算完整 ## Battle & Level diff --git a/game/tests/static_scan.sh b/game/tests/static_scan.sh index 0716a83f..245ffa6e 100644 --- a/game/tests/static_scan.sh +++ b/game/tests/static_scan.sh @@ -70,7 +70,7 @@ fi # S3 — core/ 禁 ConfigDB 外 data 表加载(schema class_name 直引豁免) # 扫描路径必须写 game/core——写裸 `core` 仓根无此目录,恒零命中恒绿(静默空转)。 -# 豁免:①注释行 ②game/core/config_db.gd 自身(数值单一事实源的正主,它的单点 load 是本规则的例外)。 +# 豁免:①注释行 ②game/core/config_db.gd 自身(数值单一事实源的现行事实源,它的单点 load 是本规则的例外)。 if require_scan_face "S3" "$DIR_CORE"; then hits=$(grep -rnE '\b(load|preload)[[:space:]]*\(|ResourceLoader\.load' "$DIR_CORE" --include='*.gd' 2>/dev/null \ | grep -vE '^[^:]+:[0-9]+:[[:space:]]*#' \ @@ -97,7 +97,7 @@ fi # 禁「板级」「门票」「正主」「落籍」「完美排雷」等退役词进注释面(完整词表见术语表解析) # 权威出处:design/gdd/术语表.md「退役词对照」节+「对外命名纪律」节 # 扫描面:game/ 全域 .gd/.tres/.md/.json/.sh(.txt 不收=第三方许可证非本仓库文本) -# 词表来源:解析「退役词对照」第一列(去括号注、斜杠拆分)+显式追加「完美排雷」;显式排除「巢穴」(玩家专名/风味层,术语表自带除外注)、「旗」(单字误报率高,doc_term_audit 判例) +# 词表来源:解析「退役词对照」第一列(去括号注、斜杠拆分)+显式追加禁「完美排雷」(受对外命名纪律约束,不在退役词对照表里);显式排除「巢穴」(玩家专名/风味层,术语表自带除外注)、「旗」(单字误报率高,doc_term_audit 判例) # 注释文本提取:.gd/.sh 取 # 后文本;.tres 取 ; 后文本;.md 取整行;.json 无注释语法(保留扩展名但不产生注释段) # 三层豁免依序:①闸门自指(行内含检查/禁令形态即跳过)②显式留档豁免单 4 处 ③非注释面天然不取 @@ -148,11 +148,11 @@ else for(i=1;i<=nw;i++){ if(index(cmt,words[i])>0){ if($0~/contains\(|find\(|grep|has_char\(|禁「|禁『|零「|零『/)next - if(FILENAME~"enemy.tres"&&NR==653)next - if(FILENAME~"level_runner"&&NR==832)next - if(FILENAME~"adventure_runner"&&NR==403)next - if(FILENAME~"damage_math_test"&&NR==36)next - print FILENAME":"NR":"words[i] + if(FILENAME~"enemy.tres"&&FNR==653)next + if(FILENAME~"level_runner"&&FNR==832)next + if(FILENAME~"adventure_runner"&&FNR==403)next + if(FILENAME~"damage_math_test"&&FNR==36)next + print FILENAME":"FNR":"words[i] next } } @@ -167,8 +167,8 @@ else for(i=1;i<=nw;i++){ if(index(cmt,words[i])>0){ if($0~/contains\(|find\(|grep|has_char\(|禁「|禁『|零「|零『/)next - if(FILENAME~"enemy.tres"&&NR==653)next - print FILENAME":"NR":"words[i] + if(FILENAME~"enemy.tres"&&FNR==653)next + print FILENAME":"FNR":"words[i] next } } @@ -182,7 +182,7 @@ else for(i=1;i<=nw;i++){ if(index($0,words[i])>0){ if($0~/contains\(|find\(|grep|has_char\(|禁「|禁『|零「|零『/)next - print FILENAME":"NR":"words[i] + print FILENAME":"FNR":"words[i] next } } diff --git a/game/tests/unit/core/feat_vouchers_test.gd b/game/tests/unit/core/feat_vouchers_test.gd index 1aff0b32..6b1c555d 100644 --- a/game/tests/unit/core/feat_vouchers_test.gd +++ b/game/tests/unit/core/feat_vouchers_test.gd @@ -171,7 +171,7 @@ func _init() -> void: "判定相减:误标 1 − 豁免 1 = 有效 0 且标中≥1 → 完美成立〔卡② R2 真值表〕") orch._perfect_hit_true = 0 Kit.check_quiet(not orch.perfect_sweep_earned(), - "判定守卫:标中数 0 时零误标也不成立(板级 ≥1 标中条件零松动)〔卡② R2 真值表〕") + "判定守卫:标中数 0 时零误标也不成立(整图 ≥1 标中条件零松动)〔卡② R2 真值表〕") var rig_rng2 = RngScript.new() rig_rng2.set_master_seed(778002) var orch2 = RigScript.new(db, rig_rng2) diff --git a/game/tests/unit/core/pool_case_d_test.gd b/game/tests/unit/core/pool_case_d_test.gd index 550da6b2..c22b3805 100644 --- a/game/tests/unit/core/pool_case_d_test.gd +++ b/game/tests/unit/core/pool_case_d_test.gd @@ -95,7 +95,7 @@ func check_v7(a, db) -> void: if String(t.get("tier", "")) != "common": ok_fb = false Kit.check_quiet(ok_fb, "子池空回退全池:全普通池候选恒 3 格普通档〔专长批 V7〕") - # 构成③:凭证不进子池也不进全池视图(独立计数体系——只经门票注入出现) + # 构成③:凭证不进子池也不进全池视图(独立计数体系——只经专长凭证注入出现) a._curio_deck = [_tok("gp", "common"), _tok("attack", "common"), _tok("max_hp", "common"), _tok("feat_ticket", "excellent")] var ticket_seen := false diff --git a/game/tests/unit/data_config/config_db_test.gd b/game/tests/unit/data_config/config_db_test.gd index 7c040828..dca3b48f 100644 --- a/game/tests/unit/data_config/config_db_test.gd +++ b/game/tests/unit/data_config/config_db_test.gd @@ -130,7 +130,7 @@ func _rows_contain(pool: Array, row: Dictionary) -> bool: func _test_shop_accessors(db) -> void: var products: Array = db.shop_products() if products.is_empty(): - Kit.check("ShopTable products 行族非空(表已落籍前提)", false) + Kit.check("ShopTable products 行族非空(表已已入库前提)", false) return Kit.check("ShopTable products 行族非空", true) var first: Dictionary = products[0] diff --git a/game/tests/unit/presentation/reward_overlay_test.gd b/game/tests/unit/presentation/reward_overlay_test.gd index 1d585c97..c619ca07 100644 --- a/game/tests/unit/presentation/reward_overlay_test.gd +++ b/game/tests/unit/presentation/reward_overlay_test.gd @@ -38,7 +38,7 @@ func _run() -> void: ov.visible and btns == 3 and not ov._confirm_btn.visible and not ov._continue_btn.visible): return # ①b 刷新面投喂(对齐商店 MC-1——投喂前隐藏/免费位点亮/GP 付费档禁用态/真实钮路径外发) - if not _req("投喂前刷新钮应隐藏(未投喂上下文如店内门票面无刷新)", + if not _req("投喂前刷新钮应隐藏(未投喂上下文如店内专长凭证面无刷新)", not ov._refresh_btn.visible): return var refreshed := [] From 1bbbdba48acb7a18e71927658670f1bf1573ba72 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 20:48:59 +0800 Subject: [PATCH 25/59] =?UTF-8?q?fix(T7/N7):=20=E5=BD=92=E5=9B=A0=E9=94=9A?= =?UTF-8?q?=E6=94=B9=E7=94=A8=E6=9C=89=E6=95=88=E8=AF=AF=E6=A0=87=E5=88=A4?= =?UTF-8?q?=E6=8D=AE=20+=20=5Femit=5Frow=20=E5=90=8E=E7=A7=BB=20+=20?= =?UTF-8?q?=E4=B8=A4=E6=80=81=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - _emit_row("seal_miss") 后移到 _fx_emit("seal_missed") 循环之后,使 _perfect_forgiven 先就位 - 判据从 RAW(_perfect_hit_false==1)改为有效误标(hit_false - forgiven == 1) - battle_log_view seal_miss 文案两态:已破态加金框、豁免态普通色 - "本板"→"本图" 概念对齐 - 修复 suffix 变量遮蔽(改名 miss_note) --- game/core/settlement/grant_segment.gd | 6 ++---- game/presentation/views/battle_log_view.gd | 7 ++++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/game/core/settlement/grant_segment.gd b/game/core/settlement/grant_segment.gd index fe6a4d9a..59a0bc30 100644 --- a/game/core/settlement/grant_segment.gd +++ b/game/core/settlement/grant_segment.gd @@ -296,10 +296,6 @@ func _judge_seal(evt: Dictionary, ri: int) -> void: if oc._seal_miss_seen.has(cell): return # 每格实例一次去重(归因行与负向兑付同键——防逐轮惩罚轰炸) oc._seal_miss_seen[cell] = true - var hl := "" - if oc._perfect_hit_false == 1: - hl = "perfect_broken" # 本板完美谓词已破的归因锚 - oc._emit_row("seal_miss", "seal_miss", cell, ri, "封印未中", 0, {}, hl) # 危险直觉·守挂点(seal_missed 发射:契约 12 触发主语=「当回合发生的标错 # 动作」——去重闸=新旧标错判别器〔后续轮重判旧封印被闸挡回零触发〕;双条件②「结算时封印仍在 # 场」由发射面既有过滤承载〔被挖开的封印已随挖掘擦除零兑付〕;grant_ap mode:queue 下一轮 @@ -315,6 +311,8 @@ func _judge_seal(evt: Dictionary, ri: int) -> void: _apply_counter_hit(h) # 豁免同时记账(insurance_used battle 域——下次标错 when lt 1 不再命中) oc._emit_row("insurance_used", "seal_miss", cell, ri, "完美保险·标错豁免", 0, {"forgiven": oc._perfect_forgiven}, "") + var hl := "perfect_broken" if oc._perfect_hit_false - oc._perfect_forgiven == 1 else "" + oc._emit_row("seal_miss", "seal_miss", cell, ri, "封印未中", 0, {}, hl) var snap = oc._reward_economy.grant(cell) if not (snap is Dictionary): return diff --git a/game/presentation/views/battle_log_view.gd b/game/presentation/views/battle_log_view.gd index 11c7fa04..905e7cf4 100644 --- a/game/presentation/views/battle_log_view.gd +++ b/game/presentation/views/battle_log_view.gd @@ -189,7 +189,12 @@ func _format_row(row: Dictionary, agg_count := -1) -> String: var n := (" ×%d" % agg_count) if agg_count > 1 else "" return prefix + "[s][color=#%s]⚠ %s%s[/color][/s]%s" % [UiKit.HEX_LOG_VOIDED, name_, n, suffix] "seal_miss": - var body := "✗ %s%s" % [name_, "(本板完美封印已破——归因此封印)" if hl == "perfect_broken" else ""] + var miss_note := "" + if hl == "perfect_broken": + miss_note = "(本图完美封印已破——清图奖励不再加倍)" + elif hl == "": + miss_note = "(首次封印落空已豁免——不计入完美封印判定)" + var body := "✗ %s%s" % [name_, miss_note] return prefix + (_gold_frame(body) if hl == "perfect_broken" else "[color=#%s]%s[/color]" % [UiKit.HEX_LOG_ROUND, body]) "cast": # 施放行:增益技 0 伤害施放,具名技能 From b3b77ff1b70b2b2d05627bc586c9c88b9f8ceb3a Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 22:24:34 +0800 Subject: [PATCH 26/59] =?UTF-8?q?test(T7/N7):=20=E6=96=B0=E5=A2=9E=20A10?= =?UTF-8?q?=E2=80=93A12=20=E4=B8=A4=E6=80=81=E6=AD=A3=E5=90=91=E6=96=AD?= =?UTF-8?q?=E8=A8=80=EF=BC=88seal=5Fmiss=20=E8=A1=8C=20highlight=20+=20=5F?= =?UTF-8?q?format=5Frow=20=E9=9B=B6=E3=80=8C=E9=9B=B7=E3=80=8D=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A10 未豁免态 highlight==perfect_broken+完美不成立;A11 豁免态 highlight==空+完美仍成立; A12 呈现两态文案含已破/已豁免且零「雷」字面。落点 feat_vouchers_test.gd,随 N7 同轮。 --- game/tests/unit/core/feat_vouchers_test.gd | 71 ++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/game/tests/unit/core/feat_vouchers_test.gd b/game/tests/unit/core/feat_vouchers_test.gd index 6b1c555d..a48c6090 100644 --- a/game/tests/unit/core/feat_vouchers_test.gd +++ b/game/tests/unit/core/feat_vouchers_test.gd @@ -187,6 +187,77 @@ func _init() -> void: "跨战清零:domain=battle 豁免账每战重建——次战首次标错再豁免一次〔卡② R2〕") Kit.check_quiet(EffectEngineKindProbe(db), "词表闭集:forgive_seal_miss 在 EFFECT_KINDS(出域即加载致命——扩签合规)〔卡② R4〕") + # ── N7 归因锚两态验收组(卡① T7:seal_miss 行 highlight 改用有效误标判据)── + # A10 未豁免态:无 perfect_insurance,首次标错 → seal_miss 行 highlight=="perfect_broken" 且完美不成立 + var rows10: Array[Dictionary] = [] + var rng10 = RngScript.new() + rng10.set_master_seed(779010) + var o10 = RigScript.new(db, rng10) + o10.step_row.connect(func(row): rows10.append(row)) + Kit.check_quiet(o10.begin_battle({"level_index": 1, "node_depth": 0, "hero_hp": 40, "hero_atk": 8, "hero_max_hp": 40, + "hero_armor_class": 10, "hero_ap_bonus": 0, "attunement": [], "attune_charges": {}, + "feats": [], "tree_rules": [], "battle_index": 1, + "bonus_ref": {"atk": 0, "max_hp": 0, "armor_class": 0}, "adventure_counters": {}, + "voucher_rap": 0, "voucher_time_sand": 0, "node_type": "battle"}), + "A10 rig:无保险战斗启动〔卡① N7〕") + var sc10: Variant = null + for c10 in o10.minesweeper.current_board().all_cells(): + if not o10.minesweeper.current_board().is_mine(c10): + sc10 = c10 + break + o10._grant_seg._judge_seal({"cell": sc10, "hit": false}, 1) + var sm10: Dictionary = {} + for r10 in rows10: + if String(r10.get("type", "")) == "seal_miss": + sm10 = r10 + Kit.check_quiet(String(sm10.get("highlight", "")) == "perfect_broken", + "A10 未豁免:首次标错 seal_miss 行 highlight==perfect_broken〔卡① N7〕") + Kit.check_quiet(not o10.perfect_sweep_earned(), + "A10 真值:无保险首标 → 有效误标 1 → 完美不成立(与 highlight 一致)〔卡① N7〕") + + # A11 豁免态:有 perfect_insurance,首次标错 → seal_miss 行 highlight=="" 且完美仍成立 + var rows11: Array[Dictionary] = [] + var rng11 = RngScript.new() + rng11.set_master_seed(779011) + var o11 = RigScript.new(db, rng11) + o11.step_row.connect(func(row): rows11.append(row)) + Kit.check_quiet(o11.begin_battle({"level_index": 1, "node_depth": 0, "hero_hp": 40, "hero_atk": 8, "hero_max_hp": 40, + "hero_armor_class": 10, "hero_ap_bonus": 0, "attunement": [], "attune_charges": {}, + "feats": ["perfect_insurance"], "tree_rules": [], "battle_index": 1, + "bonus_ref": {"atk": 0, "max_hp": 0, "armor_class": 0}, "adventure_counters": {}, + "voucher_rap": 0, "voucher_time_sand": 0, "node_type": "battle"}), + "A11 rig:带保险战斗启动〔卡① N7〕") + var sc11: Variant = null + for c11 in o11.minesweeper.current_board().all_cells(): + if not o11.minesweeper.current_board().is_mine(c11): + sc11 = c11 + break + o11._grant_seg._judge_seal({"cell": sc11, "hit": false}, 1) + var sm11: Dictionary = {} + for r11 in rows11: + if String(r11.get("type", "")) == "seal_miss": + sm11 = r11 + Kit.check_quiet(String(sm11.get("highlight", "")) == "", + "A11 豁免:首次标错获豁免 → seal_miss 行 highlight==空串〔卡① N7〕") + o11._perfect_hit_true = 1 + Kit.check_quiet(o11.perfect_sweep_earned(), + "A11 真值:误标 1 − 豁免 1 = 有效 0 且标中≥1 → 完美成立(与 highlight==空 一致)〔卡① N7〕") + + # A12 呈现两态文案与 _format_row 一致:两态均零「雷」字面 + var LogViewScript := load("res://presentation/views/battle_log_view.gd") + 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], + "round_index": 1, "display_name": "封印未中", "value": 0} + var s_broken := String(lv._format_row(broken_row)) + var s_forgiven := String(lv._format_row(forgiven_row)) + Kit.check_quiet(s_broken.find("完美封印已破") >= 0 and s_broken.find("雷") == -1, + "A12 已破态:_format_row 输出「完美封印已破」且零「雷」字面〔卡① N7〕") + Kit.check_quiet(s_forgiven.find("已豁免") >= 0 and s_forgiven.find("雷") == -1, + "A12 豁免态:_format_row 输出「已豁免」且零「雷」字面〔卡① N7〕") + lv.free() + sm.clear_breakpoint() quit(Kit.finish("feat_vouchers")) From 9a4eddba3f93f36be48355fee5ab8392188ea526 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 22:28:53 +0800 Subject: [PATCH 27/59] =?UTF-8?q?docs(=E5=8D=A1=E2=91=A0=E4=BA=A7=E5=87=BA?= =?UTF-8?q?=E7=89=A9):=20=E5=AE=9E=E7=8E=B0=E6=8A=A5=E5=91=8A=EF=BC=8B?= =?UTF-8?q?=E4=BB=A3=E6=8B=8D=E6=9D=BF=E8=BF=BD=E8=AE=A4=E5=8D=95=EF=BC=8B?= =?UTF-8?q?=E5=8F=8D=E5=93=BA=E7=82=B9=E6=B8=85=E5=8D=95=E4=B8=89=E4=BB=BD?= =?UTF-8?q?=E8=90=BD=20reports/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实现报告含改前改后读数对照、N7 修正、A10–A12、变异验证表、parity 已记档差异两例、06 重锚登记; 反哺点 16 条(GDD 九篇完美排雷→完美封印措辞、07 目检入册、移交归类、词表扩收、卡片与现实偏差)。 --- reports/iter32-卡①代拍板-2026-10-20.md | 17 ++++++ reports/iter32-卡①反哺点-2026-10-20.md | 44 ++++++++++++++ reports/iter32-卡①实现报告-2026-10-20.md | 77 ++++++++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 reports/iter32-卡①代拍板-2026-10-20.md create mode 100644 reports/iter32-卡①反哺点-2026-10-20.md create mode 100644 reports/iter32-卡①实现报告-2026-10-20.md diff --git a/reports/iter32-卡①代拍板-2026-10-20.md b/reports/iter32-卡①代拍板-2026-10-20.md new file mode 100644 index 00000000..e350fbcf --- /dev/null +++ b/reports/iter32-卡①代拍板-2026-10-20.md @@ -0,0 +1,17 @@ +# 迭代 32 卡① 代拍板追认单(2026-10-20) + +批次内落入卡片 §9 代拍板白名单的微决策,逐条备案确认(授权发生于卡片审问阶段,实现只执行预授权)。 + +| # | 决策 | 白名单条目 | 落点 | +|---|---|---|---| +| 1 | 注释换代措辞等价微调:`static_scan.sh:73`「数值单一事实源的正主」→「数值单一事实源自身」(等价表述,非硬套「现行事实源」致句意断裂) | §9.1 | static_scan.sh:73 | +| 2 | `落籍`→`已入库` 在带 commit 号(9cc4b8b)的历史注记行不改,保留「已落籍」 | §9.2 | enemy.tres:653 | +| 3 | `正主` 误报处「正主角池」(正主+角池)不改 | §9.3 | damage_math_test.gd:36 | +| 4 | 测试断言描述文本替换措辞取语义等价 | §9.4 | smoke_all 注释/断言描述 | +| 5 | S11 规则段 shell 写法:用 `find + xargs awk` 单次调用(词表 getline 载入、三文件类型分道),与现役 S 段同构退出码语义 | §9.5 | static_scan.sh S11 段 | +| 6 | N7 两态文案末字:已破态「清图奖励不再加倍」、豁免态「不计入完美封印判定」,因果不变成立 | §9.6 | battle_log_view.gd:192 | +| 7 | battle_log_view 局部变量改名 `suffix`→`miss_note` 避开外层同名遮蔽(实现细节,非语义) | §9.5 延伸 | battle_log_view.gd | + +**超白名单呈报(已停机自查消解,非代裁)**: +- 卡片 §2 豁免单预测的 `level_runner.gd:832`、`adventure_runner.gd:403` 两处,开工复核发现现行代码该行已无对应退役词(卡片成文后代码前进)。据「开工自行复核」条款按现实处理:无需豁免(词已不在该位),S11 注释面为权威判据。不新增豁免、不改代码凑绿。 +- 全局 sed 曾误改移交三处(display_name/玩家文案)与 static_scan.sh 词表追加行,已逐处精确还原并补 S11 自指豁免,属施工返工非代拍板。 diff --git a/reports/iter32-卡①反哺点-2026-10-20.md b/reports/iter32-卡①反哺点-2026-10-20.md new file mode 100644 index 00000000..8bf5ad2c --- /dev/null +++ b/reports/iter32-卡①反哺点-2026-10-20.md @@ -0,0 +1,44 @@ +# 迭代 32 卡① 反哺点清单(2026-10-20) + +本批为代码实现批,禁写 `design/` 整目录与根规则文件。发现要改文档的点逐条列此,用户在会话裁决后归文档批落文(`design/` 对本批只读)。落点对应卡片 §5 关联文档同步面。 + +## GDD 文档面(「完美排雷」→「完美封印」措辞同步) + +| # | 文档 | 关联点 | 建议改成 | 依据 | +|---|---|---|---|---| +| 1 | `design/gdd/术语表.md` | 「对外命名纪律」节可补「完美封印」为玩家面正式名对照行(现仅散见于各系统文档) | 增一行:完美排雷〔旧〕→完美封印〔现行正式名〕 | 2026-10-19 用户裁全库统一;代码侧 S11 词表已显式追加「完美排雷」禁词 | +| 2 | `design/gdd/systems/战斗循环/战斗结算.md`(:85/:108/:116/:139/:141/:161/:259/:342) | 全篇仍称「完美排雷」,与 `奇物.md` v3.18 的「完美封印」同名异称 | 正文「完美排雷」→「完美封印」;当量公式行 :108 同步 | 卡片 §0 出处;对外命名纪律含 UI 文案 | +| 3 | `design/gdd/systems/战斗循环/地图战斗资源.md`(:155/:194) | 兑付结构段称「完美排雷」 | →「完美封印」 | 同上 | +| 4 | `design/gdd/systems/战斗循环/战斗表现.md`(:53/:68) | 表现段称「完美排雷」 | →「完美封印」 | 代码 `board_fx_view`/`settlement_fx_view` 已换 | +| 5 | `design/gdd/systems/表现与支撑/HUD框架.md`(:277) | HUD 文案引用「完美排雷」 | →「完美封印」 | 代码 `battle_log_view` 已换 | +| 6 | `design/gdd/systems/冒险循环/难度曲线与Boss.md`(:224/:227/:313) | 「完美排雷」措辞 | →「完美封印」 | 同名异称统一 | +| 7 | `design/gdd/ux/battle.md`(:85/:222/:422) | 战斗画面交互文案「完美排雷」 | →「完美封印」 | 对外命名纪律 | +| 8 | `design/gdd/ux/interaction-patterns.md`(:90) | 「完美排雷」 | →「完美封印」 | 同上 | +| 9 | `design/art/art-bible.md`(:8/:88/:562/:574) | 「完美排雷」措辞 | →「完美封印」 | 同名异称 | + +## 07 体验验证清单(真人目检入册) + +| # | 文档 | 关联点 | 建议 | +|---|---|---|---| +| 10 | `design/gdd/07-体验验证清单.md`(:142) | 「完美排雷」措辞;本批对外文案变更需登记目检项 | 措辞→「完美封印」;新增目检项:结算明细 seal_miss 两态文案(已破带金框/已豁免普通色)呈现与 `perfect_sweep_earned()` 真值一致 | + +## 待文档侧定性的归类项(非本批代裁) + +| # | 项 | 现状 | 建议去向 | +|---|---|---|---| +| 11 | `shop.tres:86`「奇物门票」display_name + `curio_interact_controller.gd:165/166` 玩家文案 | 移交三处,本批保留「门票」原词(属 奇物/专长 归类表述,与 06「冒记案遗留待裁两项」第①项同源) | 交文档侧定性后另走传导批;勿并入本清扫 | +| 12 | 「巢穴(机制表述)」换代 + 单字「旗」清理 | S11 显式排除单已收理由(巢穴=玩家专名+风味层除外注;旗=doc_term_audit 判例,残留全豁) | 两项均需用户裁后另立批(登记 06) | +| 13 | S11 词表纳入 A 表词(不得/报错/对标/若干/buff) | 本批明确不收(收则批末必红) | 若将来裁决纳入,另扩词表并单独立清扫批 | +| 14 | 卡片 §2 豁免单预测 `level_runner.gd:832`、`adventure_runner.gd:403` | 开工复核:现行代码该行已无对应退役词(卡片成文后代码前进) | 反哺点记录卡片与现实偏差;卡片如需订正归文档批 | + +## parity 重锚批(登记 06) + +| # | 项 | 建议 | +|---|---|---| +| 15 | N7 改动致 `seal_miss`/`insurance_used` 行序与 highlight 漂移(契约 12) | 合回后另立**用户批准**的 parity 重锚批并登记 06;预期漂移两例见实现报告「已记档差异」节 | + +## 06 待办清单 + +| # | 项 | 建议 | +|---|---|---| +| 16 | 本批条目「代码注释禁用词清扫」状态推进 | 卡①合回后由文档批推进至「实现已闭合」;本批不写 06 | diff --git a/reports/iter32-卡①实现报告-2026-10-20.md b/reports/iter32-卡①实现报告-2026-10-20.md new file mode 100644 index 00000000..2dc48afc --- /dev/null +++ b/reports/iter32-卡①实现报告-2026-10-20.md @@ -0,0 +1,77 @@ +# 迭代 32 卡① 实现报告·代码注释禁用词清扫批(2026-10-20) + +- **批次**:迭代 32 执行序①(代码注释禁用词清扫批) +- **分支**:`g-plan2-iter32-card1-comment-sweep` +- **合回前 tip**:`b3b77ff1` +- **闸回执**:`game/tests/.gates/receipt.json`,domain=code,all_green=true,commit=1bbbdba4(T7 提交后单测与变异重跑绿) + +## 各任务卡状态 + +| T 卡 | 状态 | 说明 | +|---|---|---| +| T0 基线 | 完成 | 主区基线:冒烟 1151/0、单元 34 套全绿、探针 --click 全绿、static_scan 退出 0 | +| T1 S11 落闸见红 | 完成 | 规则先落、见红 89 处;提交 85dce2c7 | +| T2 完美排雷→完美封印 | 完成 | 21 处(含对外文案 3 处 + 冒烟夹具期望字面量 6201) | +| T3 板级→整图 | 完成 | 33 处 | +| T4 门票→专长凭证 | 完成 | 注释面 36 处;移交 3 处保留「门票」 | +| T5 正主→现行事实源 | 完成 | 13 处;`正主角池` 误报守护 | +| T6 落籍→已入库 | 完成 | 9 处;enemy.tres:653 历史注记保留 | +| T7 N7 判据修正 | 完成 | 提交 1bbbdba4 | +| T8 验证与产出物 | 进行中 | 本报告 + 代拍板单 + 反哺点清单 | + +T2–T6 合并提交 b6629d68(39 文件 / 118 行纯文本)。 + +## 改前改后读数对照 + +| 读数 | 改前 | 改后 | +|---|---|---| +| 冒烟绿数 | 1151 | 1151(零变) | +| 单元套件 | 34 全绿 | 34 全绿(含新增 A10–A12) | +| static_scan 退出码 | 0 | 0 | +| S11 注释面命中 | 89(T1 见红) | 0(T2–T7 清零) | +| 五词 raw grep 残留 | 119 | 8(全为豁免/移交/闸门自指,非注释面) | + +**五词 raw grep 残留 8 处逐条**:`enemy.tres:653`(落籍·豁免·历史注记)、`shop.tres:86`(门票·移交 display_name)、`curio_interact_controller.gd:165/166`(门票·移交玩家文案)、`static_scan.sh:97/100/122`(完美排雷·S11 闸门自指)、`damage_math_test.gd:36`(正主角池·误报豁免)。 +注:卡片 §2 豁免单预测的 `level_runner.gd:832`、`adventure_runner.gd:403` 经开工复核,现行代码该行已无对应退役词(卡片成文后代码前进),故不出现;S11 注释面口径为权威判据,现绿。 + +## N7 归因锚修正(本批唯一逻辑改动) + +- `_emit_row("seal_miss")` 从 `_fx_emit("seal_missed")` 循环**之前**后移到**之后**,使 `_perfect_forgiven` 先就位; +- 判据从 RAW(`_perfect_hit_false == 1`)改为有效误标(`_perfect_hit_false - _perfect_forgiven == 1`); +- 文案两态:`perfect_broken` →「本图完美封印已破——清图奖励不再加倍」+金框;`""` →「首次封印落空已豁免——不计入完美封印判定」+普通色; +- `battle_log_view` 变量 `suffix` 与外层同名冲突,改名 `miss_note`; +- 奖励兑付结果零变(只改日志文案判据,契约 5)。 + +## 验收断言 A10–A12(落 feat_vouchers_test.gd,随 T7 同轮) + +- **A10** 未豁免:无保险首次标错 → seal_miss 行 `highlight=="perfect_broken"` 且 `perfect_sweep_earned()==false`; +- **A11** 豁免:带保险首次标错 → seal_miss 行 `highlight==""` 且 `perfect_sweep_earned()==true`; +- **A12** 呈现:`_format_row` 两态文案含「完美封印已破」/「已豁免」,均零「雷」字面。 + +## 变异验证记录表 + +| 变异点 | 注入形态 | 跑的闸 | 红输出 | 还原 | +|---|---|---|---|---| +| S11 拦截 | battle_orchestrator.gd:265 注释追加「板级」 | static_scan.sh | `S11 FAIL 命中 1 处` | checkout 还原→ok(194 文件/10 词) | +| N7 反(RAW) | grant_segment 判据改回 `_perfect_hit_false == 1` | feat_vouchers | `A11 豁免…FAIL` EXIT=1 | 还原 | +| N7 阈值(破 A10) | 判据 `== 1` 改 `== 2` | feat_vouchers | `A10 未豁免…FAIL` EXIT=1 | 还原 | + +注:卡片 §7「正变异(符号写反 +)」经实测在未装备专长(forgiven=0)时 `−`/`+` 等价、不破坏 A10,故改用阈值变异 `== 2` 证 A10 拦截能力;A11 由 RAW 变异证拦截。A12 为文案常量比对,随 A10/A11 判据承载,无独立变异。 + +## 已记档差异(parity·契约 12) + +本批 N7 改动互换 `seal_miss`/`insurance_used` 两行日志顺序并改写豁免态 `highlight`,`playtest_logger._on_step_row` 逐行落盘含 `highlight` 字段,11 号闸 JSONL sha256 逐位比对必红。**本批不发起 parity**(回执 11 号落 skip、入 not_run,all_green 不受影响)。 + +预期漂移两例(供合回后用户批准重锚批对照): +1. **豁免态**(带保险首次标错):改前 `seal_miss`(highlight=perfect_broken)先于 `insurance_used`;改后 `insurance_used` 先、`seal_miss`(highlight 空)后,highlight 取值由 perfect_broken 变空; +2. **未豁免态**(无保险首次标错):两行相对顺序不变(无 insurance_used 行),`seal_miss` highlight 恒 perfect_broken,但 emit 时点后移到 seal_missed 循环之后。 + +## 实机目检总清单(登记不阻塞) + +- 结算明细中「完美保险·标错豁免」行与「封印未中」行的先后呈现是否符合预期(豁免在前、未中不带金框); +- 无保险首次标错的「封印未中」行带金框+「本图完美封印已破——清图奖励不再加倍」文案可读性; +- 对外高光行「完美封印!清图奖励 ×2」与 banner「完美封印 ×2」显示正确。 + +## 遗留读数义务 + +- 合回后另立**用户批准**的 parity 重锚批(登记 06),本批不借任何批顺手重锚。 From a8db22579946f8b7c0b3eed8fc1b7ad1f1b86162 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 22:44:21 +0800 Subject: [PATCH 28/59] =?UTF-8?q?fix(=E5=8D=A1=E2=91=A1=20T0=E9=A6=96?= =?UTF-8?q?=E6=8F=90=E4=BA=A4):=20=E9=87=87=E9=9B=86=E5=99=A8=20rules=20?= =?UTF-8?q?=E6=A1=A3=20tree=5Frules=20=E7=B1=BB=E5=9E=8B=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E2=80=94=E2=80=94Array=20=E5=8C=85=E8=A3=B9=20split=20?= =?UTF-8?q?=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit String.split() 产 PackedStringArray,被 adventure_runner.gd:118/:200 的 is Array 守卫整组静默丢弃, 致 rules 档与 off 档逐位相同(分组空转、V12 rules 组恒假绿)。测试工具类型修复,无玩法改动。 --- game/smoke/adventure_monte_carlo.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game/smoke/adventure_monte_carlo.gd b/game/smoke/adventure_monte_carlo.gd index 28ba0148..e90ffb8f 100644 --- a/game/smoke/adventure_monte_carlo.gd +++ b/game/smoke/adventure_monte_carlo.gd @@ -62,7 +62,7 @@ func _initialize() -> void: elif feat_mode == "ab_b": feat_profile = {"mode": "off", "tree_rules": ["posture_bulwark"]} elif feat_mode == "rules": - feat_profile = {"mode": "off", "tree_rules": String(args[7] if args.size() >= 8 else "").split(",")} # V19——任意键集配对注入 + feat_profile = {"mode": "off", "tree_rules": Array(String(args[7] if args.size() >= 8 else "").split(",", false))} # V19——任意键集配对注入(Array 包裹防 PackedStringArray 被 adventure_runner is Array 守卫整组丢弃) var db = load("res://core/config_db.gd").new() if not db.load_tables("res://data/tables", false): print("表加载失败") From ae5baed699dee36f0727980a9430282d3f553795 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 22:55:28 +0800 Subject: [PATCH 29/59] =?UTF-8?q?feat(=E5=8D=A1=E2=91=A1=20T1):=20EffectCo?= =?UTF-8?q?ntext=20=E6=96=B0=E5=BB=BA=20+=20=E5=9B=9B=E5=AE=BF=E4=B8=BB?= =?UTF-8?q?=E6=8E=A5=E7=BA=BF=EF=BC=88=E5=BC=95=E6=93=8E=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=9C=AA=E5=8A=A8=C2=B7=E7=BA=AF=20ctx=20=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E6=9D=9F=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新建 game/core/effect_context.gd(四桶公开类型化字段,零方法) - BattleOrchestrator:fx_counters_round/fx_counters_battle/counters_ctx 三成员,_init 建 ctx 挂自有两桶, begin_battle 挂 adventure_bucket(=_ledger.adventure_counters) 与 level_bucket(enc["level_counters"]) - set_fx 三协同件扩 ctx 参并存 _ctx(引擎 API 暂不改,T2 动) - LevelRunner:level_counters 成员 + enc 下传 - 删 _reset_tree_limited_counters(按关清零改由 level 桶随 new 承载)+ 调用点 + 冒烟旧 V10 直呼断言 冒烟 1150/0(旧断言随函数退役,-1 项符合预期)。 --- game/core/action_economy.gd | 4 +++- game/core/adventure_runner.gd | 10 +--------- game/core/battle_orchestrator.gd | 16 +++++++++++++--- game/core/damage_controller.gd | 4 +++- game/core/effect_context.gd | 10 ++++++++++ game/core/effect_context.gd.uid | 1 + game/core/level_runner.gd | 2 ++ game/core/reward_economy.gd | 4 +++- game/smoke/smoke_all.gd | 8 +------- 9 files changed, 37 insertions(+), 22 deletions(-) create mode 100644 game/core/effect_context.gd create mode 100644 game/core/effect_context.gd.uid diff --git a/game/core/action_economy.gd b/game/core/action_economy.gd index 90c29b49..a559ad9f 100644 --- a/game/core/action_economy.gd +++ b/game/core/action_economy.gd @@ -41,12 +41,14 @@ var charge_layers: int: get: return _charge_layers # 效果引擎(dig_paid/charge_full 发射面;round_end 转存决策面) var _fx: EffectEngine = null +var _ctx: EffectContext = null var _last_stop_ap := 0 # 停手侧剩余 AP 记账(转存决策在 round_end 发射点——grant_ap(transfer) 订阅定夺) var _ap_exhausted_last := false # 上轮 AP 耗尽封印(一滴不剩 round_start when 面) -func set_fx(fx: EffectEngine) -> void: +func set_fx(fx: EffectEngine, ctx: EffectContext) -> void: _fx = fx + _ctx = ctx func _init(db_ref: ConfigDb) -> void: diff --git a/game/core/adventure_runner.gd b/game/core/adventure_runner.gd index 5c9b031c..9bc55a08 100644 --- a/game/core/adventure_runner.gd +++ b/game/core/adventure_runner.gd @@ -832,17 +832,9 @@ func abandon() -> bool: # ---- 关卡推进(私有——序列编排单一出口)---- -# 树限次计数按关重置(危险直觉锋/守两组「每关限次」账本键:跨战持久由 adventure -# 域导出/回灌承载,此处随关清零闭合生命周期四态;键集=效果引擎树合成行声明的 counter_id; -# 独立成口=V10 断言面直呼) -func _reset_tree_limited_counters() -> void: - for cid in ["tree_sense_sharp_used", "tree_sense_guard_used"]: - run_ledger.adventure_counters.erase(cid) - - func _start_current_level() -> bool: _runner = LevelRunner.new(db, rng) - _reset_tree_limited_counters() # 树限次计数按关重置(V10 生命周期四态闭合——断言面直呼本口) + # 树限次计数按关清零现由 LevelRunner.level_counters 随每关 new 天然承载(旧硬编码清除名单 _reset_tree_limited_counters 已删) # core↔core 接线只许方法 Callable(S6——lambda 捕获 self 会延长 RefCounted 生命周期乃至成环) _runner.node_entered.connect(_forward_node_entered) _runner.choices_presented.connect(_forward_choices_presented) diff --git a/game/core/battle_orchestrator.gd b/game/core/battle_orchestrator.gd index ff672721..c6814bbd 100644 --- a/game/core/battle_orchestrator.gd +++ b/game/core/battle_orchestrator.gd @@ -82,6 +82,9 @@ var _feat_first_dig_used := false # 效果引擎(发布订阅解释器;begin_battle 从持有集/装备集重建订阅。 # 施加面:发射点 dispatch 返回命中,发射点按组合规则施加) var _fx: EffectEngine +var fx_counters_round: Dictionary[Variant, Variant] = {} # round 桶(轮始整桶清空;随编排器生灭) +var fx_counters_battle: Dictionary[Variant, Variant] = {} # battle 桶(无前缀 id 缺省归此;随编排器每战 new 天然空) +var counters_ctx: EffectContext = null # 四桶引用束(_init 建、begin_battle 挂 adventure/level 引用) # 事件发射薄面(18 发射点统一入口——订阅空=零循环零扰动;确定性同步分发零 RNG) @@ -269,6 +272,9 @@ func _init(db_ref: ConfigDb, rng_ref: RngServiceCore) -> void: db = db_ref rng = rng_ref _fx = EffectEngine.new(db_ref) + counters_ctx = EffectContext.new() + counters_ctx.round_bucket = fx_counters_round # 挂自有两桶引用(与编排器成员字段同物异名同字典) + counters_ctx.battle_bucket = fx_counters_battle _board_generator = BoardGenerator.new() action_economy = ActionEconomy.new(db) minesweeper = MinesweeperRules.new(db, action_economy) @@ -277,9 +283,9 @@ func _init(db_ref: ConfigDb, rng_ref: RngServiceCore) -> void: _reward_economy = RewardEconomy.new(db, rng) _damage = DamageController.new(db, rng, _enemy_system, _status_effects) _damage.emit_row_cb = _emit_row # 行协议归属本类(9 类行协议 + 来源断言不外泄) - _damage.set_fx(_fx) # 效果引擎注入(attack_commit/clamp_check/armor_roll/kill/damage_taken 发射面) - action_economy.set_fx(_fx) # dig_paid/charge_full 发射面 - _reward_economy.set_fx(_fx) # reward_roll 发射面 + _damage.set_fx(_fx, counters_ctx) # 效果引擎注入(attack_commit/clamp_check/armor_roll/kill/damage_taken 发射面) + action_economy.set_fx(_fx, counters_ctx) # dig_paid/charge_full 发射面 + _reward_economy.set_fx(_fx, counters_ctx) # reward_roll 发射面 minesweeper.cell_revealed.connect(_on_cell_revealed) minesweeper.seal_judged.connect(_on_seal_judged) minesweeper.round_end_board.connect(_on_round_end) @@ -371,6 +377,10 @@ func begin_battle(enc: Dictionary) -> bool: _fx_bonus_delta = {"atk": 0, "max_hp": 0, "armor_class": 0, "ap": 0} var ledger_ref = enc.get("ledger", null) _ledger = ledger_ref if ledger_ref is RunLedger else RunLedger.new() # 缺省新账=调试/单场零扰动面 + counters_ctx.adventure_bucket = _ledger.adventure_counters # 挂冒险桶引用(跨战持久=同一字典引用,非副本搬运) + var level_ref: Variant = enc.get("level_counters") + if level_ref is Dictionary: + counters_ctx.level_bucket = level_ref # 挂关卡桶引用(LevelRunner 每关 new 下传) _damage.fx_reveal_request = _fx_enqueue_reveal _damage.fx_ac_request = _apply_ac_bonus var feat_ids: Array[Variant] = enc.get("feats", []) as Array diff --git a/game/core/damage_controller.gd b/game/core/damage_controller.gd index 59c49907..9e4fc7a7 100644 --- a/game/core/damage_controller.gd +++ b/game/core/damage_controller.gd @@ -44,6 +44,7 @@ var _hero_ac_override := -1 # 主角护甲等级合流入参(begin_battle # 效果引擎(attack_commit/clamp_check/armor_roll/kill/damage_taken # 发射+施加面:dispatch 返回命中,本类按组合规则施加) var _fx: EffectEngine = null +var _ctx: EffectContext = null # 战斗段运行态事实(编排器每轮刷新——fact 取数面:attack_commit 载荷 dig_streak / # charge_layers facts〔猎巢人 per/整备 attack_bonus per/厚积薄发 when/铁壁 shield per〕; # 流派档位两运行态〔magic 档一 rider+1 / 档二 rider 可暴击〕) @@ -67,8 +68,9 @@ func set_hero_ac_override(v: int) -> void: # 效果引擎注入(战斗编排器 _init——事件发射面接线) -func set_fx(fx: EffectEngine) -> void: +func set_fx(fx: EffectEngine, ctx: EffectContext) -> void: _fx = fx + _ctx = ctx # 事件发射薄面(发射+命中收集统一入口——订阅空=零循环零扰动;命中由各施加面按组合规则施加) diff --git a/game/core/effect_context.gd b/game/core/effect_context.gd new file mode 100644 index 00000000..d859a160 --- /dev/null +++ b/game/core/effect_context.gd @@ -0,0 +1,10 @@ +## EffectContext——效果引擎四桶计数器引用束(无状态引擎的外部状态承载)。 +## 四桶按生命周期分:round(轮始整桶清空)/battle(随编排器生灭)/level(随 LevelRunner 生灭)/ +## adventure(随 RunLedger 生灭)。本类零方法零行为,只持引用;桶容器由宿主对象 new,本类只挂引用。 +class_name EffectContext +extends RefCounted + +var round_bucket: Dictionary[Variant, Variant] = {} +var battle_bucket: Dictionary[Variant, Variant] = {} +var level_bucket: Dictionary[Variant, Variant] = {} +var adventure_bucket: Dictionary[Variant, Variant] = {} diff --git a/game/core/effect_context.gd.uid b/game/core/effect_context.gd.uid new file mode 100644 index 00000000..01a436bf --- /dev/null +++ b/game/core/effect_context.gd.uid @@ -0,0 +1 @@ +uid://6n45i76gkrmu diff --git a/game/core/level_runner.gd b/game/core/level_runner.gd index e304c378..64e4dad1 100644 --- a/game/core/level_runner.gd +++ b/game/core/level_runner.gd @@ -23,6 +23,7 @@ var node_index := -1 # 冒险模式 = AdventureRunner 共享字典(Dictionary 引用共享——hero_hp/gp 属性读写直接落冒险账本); # 单关模式 = 本实例私有账本(start_level 重建,既有单关语义逐位保留)。 var _ledger: Dictionary[Variant, Variant] = {"hero_hp": 0, "gp": 0} +var level_counters: Dictionary[Variant, Variant] = {} # 关卡桶(lvl_ 前缀计数器;每关随 LevelRunner new 天然空=按关清零,替代旧硬编码清除名单) var _rest_handler: Callable # 治疗封顶回报执行体(默认内置 rest_heal_amount;冒险模式 = AdventureRunner.apply_rest——接口③) var _external := false # 冒险模式标记(钱包收束时机与播种语义分叉点) # hero_hp / gp 属性化(既有读写点零改动——值类型经属性落 _ledger) @@ -469,6 +470,7 @@ func _start_battle(node: Dictionary) -> bool: "attack_type": _hero_attack_type, "armor_type": _hero_armor_type, # 两根类型轴(spawn 英雄快照;空串=锻造配置默认值回退) "attunement": _attunement, "ledger": run_ledger, # 共享四账单类下传(单引用键) + "level_counters": level_counters, # 关卡桶下传(同关跨战共享引用、随本类 new 天然空) "feats": _feats, "tree_rules": _tree_rules, "battle_index": _battle_index(), diff --git a/game/core/reward_economy.gd b/game/core/reward_economy.gd index 2bffccf3..71f685cf 100644 --- a/game/core/reward_economy.gd +++ b/game/core/reward_economy.gd @@ -18,10 +18,12 @@ var _clear_granted := false var _clear_snapshot := {} # 效果引擎(reward_roll 发射面;偏运硬币 bias_rewards 订阅面) var _fx: EffectEngine = null +var _ctx: EffectContext = null -func set_fx(fx: EffectEngine) -> void: +func set_fx(fx: EffectEngine, ctx: EffectContext) -> void: _fx = fx + _ctx = ctx func _init(db_ref: ConfigDb, rng_ref: RngServiceCore) -> void: diff --git a/game/smoke/smoke_all.gd b/game/smoke/smoke_all.gd index 8f74b2aa..ce2aba07 100644 --- a/game/smoke/smoke_all.gd +++ b/game/smoke/smoke_all.gd @@ -6119,13 +6119,7 @@ func _smoke_tree_rules() -> void: "守⑤ rig:次战编排启动(新战新队列实例)") check(int(orch2.action_economy.pending_ap_delta()) == 0, "守⑤:末轮判出不返(queue 只在 notify_round_start 兑现、战亡即弃——无跨战泄漏)") - # 按关重置清零点(adventure_runner._start_current_level) - var ar = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(777003)) - ar.run_ledger.adventure_counters = {"tree_sense_sharp_used": 2, "tree_sense_guard_used": 1, "unrelated_key": 9} # 计数账住 RunLedger - ar._reset_tree_limited_counters() - check(not ar.run_ledger.adventure_counters.has("tree_sense_sharp_used") and not ar.run_ledger.adventure_counters.has("tree_sense_guard_used") - and int(ar.run_ledger.adventure_counters.get("unrelated_key", 0)) == 9, - "限次按关重置:_start_current_level 清零点恰两键(他键零扰动——生命周期四态闭合)") + # 树限次按关清零改由 LevelRunner.level_counters 随 new 承载(旧硬编码名单冒烟断言随函数删除——换代同生死;新语义由 V4/V5 段承载) # 财富之道·散:商品标价折价(level_runner 计价单点) var lr = load("res://core/level_runner.gd").new(_db, _fresh_rng(777004)) lr.set_tree_rules([]) From a721e529ef9c930a9cd33c6c43e9cce30b35397b Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 22:57:44 +0800 Subject: [PATCH 30/59] =?UTF-8?q?feat(=E5=8D=A1=E2=91=A1=20T2):=20EffectEn?= =?UTF-8?q?gine=20=E5=88=A0=E8=BF=90=E8=A1=8C=E6=97=B6=E7=8A=B6=E6=80=81?= =?UTF-8?q?=20+=20ctx=20=E6=8E=A5=E5=8F=A3=20+=20=E9=9D=99=E6=80=81?= =?UTF-8?q?=E5=86=99=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删成员 _counters/_reset_on_round_start/_adventure_counter_ids(引擎零运行时可变状态,仅 _triggers+db) - dispatch(ctx, event, payload, facts);round_start 特判改 ctx.round_bucket.clear() 整桶就地清空 - counter/dispatch 读路径 _when_ok/_cond_ok/_fact_value 全经 ctx - 新增 static bucket_of(ctx,id)(前缀→桶唯一出处)+ counter_id_legal(只禁 meta_) - 写口改 static counter_add/counter_spend(算术逐字承旧);删实例版与 counters_export/counters_seed - 树合成行 sense 两键改名 lvl_tree_sense_*,删 domain/reset_at 键;_push_trigger 增前缀 assert - rebuild 签名不变(冒烟调用面零迁移) 调用点施加点迁移见 T3,数据行/测试冒烟迁移见 T6/T7(本提交为无状态内核检查点,全绿在批末)。 --- game/core/effect_engine.gd | 136 +++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 73 deletions(-) diff --git a/game/core/effect_engine.gd b/game/core/effect_engine.gd index 59461b6a..6b37cf99 100644 --- a/game/core/effect_engine.gd +++ b/game/core/effect_engine.gd @@ -79,12 +79,8 @@ const DO_KEYS := ["kind", "value", "value_from", "delta", "delta_from", "mult", ## 含连锁展开与格面资源,危险格仅真视显示不移除——棋盘事实不可变契约;免行动点即效果本身) const ACTIVE_KINDS := ["reveal_tiles", "preview", "grant_ap", "remove_mines", "refresh_pick", "safe_dig"] -# ---- 订阅集与计数器账本 ---- +# ---- 订阅集(编译产物=程序,非状态;计数器四桶经 ctx 外置宿主持有)---- var _triggers: Array[Variant] = [] # [{source, id, on, when, do}](装载序=声明序,重建时定死) -var _counters: Dictionary[Variant, Variant] = {} # counter_id → int(battle 域账本;重建清零;重置点由订阅行声明) -var _reset_on_round_start: Array[String] = [] # round_start 重置点计数器名单(装载时收集) -var _adventure_counter_ids: Array[String] = [] # domain=adventure 计数器名单(重建时收集、不清零; - # battle 末 export → 冒险账本、begin_battle seed 回灌) var db: ConfigDb # 矩阵/表读取(advantageous 算子消费)——可空(纯计数器用法零依赖) @@ -93,12 +89,11 @@ func _init(db_ref: ConfigDb = null) -> void: ## 订阅装载(每战 begin_battle 调用——重建时机 v1.1):feats 表序→treasure 表序(各按持有/装备 -## 集过滤)→树规则合成行。同一数据行的多个 trigger 按行内数组序。计数器账本同步清零并按订阅行 -## 声明收集重置点(round_start)。 +## 集过滤)→树规则合成行。同一数据行的多个 trigger 按行内数组序。计数器四桶由宿主持有、随宿主生灭, +## 本方法只重建订阅集(运行时可变状态=零;battle/level 桶的清零由宿主 new 天然承载,round 桶清零 +## 在 dispatch 的 round_start 特判内整桶 clear,adventure 桶随 RunLedger 引用跨战持久——无副本搬运)。 func rebuild(feat_ids: Array, item_ids: Array, tree_rules: Array = []) -> void: _triggers.clear() - _reset_on_round_start.clear() - _adventure_counter_ids.clear() if db != null and db.feats != null: for row in db.feats.rows: var fid := String(row.get("feat_id", "")) @@ -115,11 +110,9 @@ func rebuild(feat_ids: Array, item_ids: Array, tree_rules: Array = []) -> void: _push_trigger("attune", iid, tr, row) # 树规则合成订阅(六键按 v0.8 三组双态):posture 两键=「每关首轮窗」语义 # 〔battle_index==1 且 round_index==1;battle_index=关卡域战斗序由 enc 携带〕; - # sense 两组=每关限次〔adventure 域计数器 lt 上限闸 + 命中即 counter_add - # 记账双行——同事件双行同预评估态见闸同记,序=装载序确定;生命周期四态:跨战持久=domain - # adventure 导出/回灌、按关重置=AdventureRunner._start_current_level 清零、新冒险清零=账本 - # 归零、断点保留=断点快照随键〕;economy 两组零订阅行——消费点=GP 掉落乘算与商品计价折价的 - # tree_rules 成员判定(编排器/关卡 runner 读 enc 键集),不入事件面。数值全 provisional 归 M4。 + # sense 两组=每关限次〔level 桶计数器 lt 上限闸 + 命中即 counter_add 记账双行——同事件双行同 + # 预评估态见闸同记,序=装载序确定;寿命随 LevelRunner.level_counters 每关 new 天然按关清零〕; + # economy 两组零订阅行——消费点=GP 掉落乘算与商品计价折价的 tree_rules 成员判定。数值全 provisional 归 M4。 for key_v in tree_rules: var rk := String(key_v) match rk: @@ -137,30 +130,31 @@ func rebuild(feat_ids: Array, item_ids: Array, tree_rules: Array = []) -> void: # 锋=踩中危险格伤害减半·每关限次——mine_hit 挂点现成(damage_mult 收集→halve_pct, # 与惊巢反制同路径;伤害在结算战斗段末兑付,探索阶段零改动) _push_trigger("tree", rk, {"on": "mine_hit", - "when": [{"fact": "counter", "id": "tree_sense_sharp_used", "op": "lt", "value": 2}], + "when": [{"fact": "counter", "id": "lvl_tree_sense_sharp_used", "op": "lt", "value": 2}], "do": {"kind": "damage_mult", "value": 50}}, {}) _push_trigger("tree", rk, {"on": "mine_hit", - "when": [{"fact": "counter", "id": "tree_sense_sharp_used", "op": "lt", "value": 2}], - "do": {"kind": "counter_add", "counter_id": "tree_sense_sharp_used", - "value": 1, "domain": "adventure"}}, {}) + "when": [{"fact": "counter", "id": "lvl_tree_sense_sharp_used", "op": "lt", "value": 2}], + "do": {"kind": "counter_add", "counter_id": "lvl_tree_sense_sharp_used", + "value": 1}}, {}) "sense_guard": # 守=标错返还行动点·每关限次(契约 12 失误补偿——seal_missed 由 _judge_seal 去重闸后 # 发射;queue=下一轮开轮兑现,末轮判出无下一轮=合法作废自动成立) _push_trigger("tree", rk, {"on": "seal_missed", - "when": [{"fact": "counter", "id": "tree_sense_guard_used", "op": "lt", "value": 2}], + "when": [{"fact": "counter", "id": "lvl_tree_sense_guard_used", "op": "lt", "value": 2}], "do": {"kind": "grant_ap", "mode": "queue", "value": 1}}, {}) _push_trigger("tree", rk, {"on": "seal_missed", - "when": [{"fact": "counter", "id": "tree_sense_guard_used", "op": "lt", "value": 2}], - "do": {"kind": "counter_add", "counter_id": "tree_sense_guard_used", - "value": 1, "domain": "adventure"}}, {}) - # 计数器账本重建(battle 域清零;adventure 域由 counters_seed 回灌〔rebuild 后调用〕) - _counters = {} + "when": [{"fact": "counter", "id": "lvl_tree_sense_guard_used", "op": "lt", "value": 2}], + "do": {"kind": "counter_add", "counter_id": "lvl_tree_sense_guard_used", + "value": 1}}, {}) func _push_trigger(source: String, id: String, tr: Dictionary, row: Dictionary) -> void: var on := String(tr.get("on", "")) assert(EVENTS.has(on), "[效果引擎] 订阅事件出域: %s(%s %s)" % [on, source, id]) var do_d: Dictionary[Variant, Variant] = (tr.get("do", {}) as Dictionary).duplicate(true) + # 树合成行 counter_id 前缀校验(与 validate_trigger_row 同源判据;写错前缀调试期致命) + if do_d.has("counter_id") and not counter_id_legal(String(do_d.counter_id)): + assert(false, "[效果引擎] 合成行 counter_id 前缀非法: %s(%s %s)" % [String(do_d.counter_id), source, id]) # *_from 解析(rebuild 时把行字段引用定影为值——value_from:"magnitude" → value=行 magnitude) for pair in [["value_from", "value"], ["delta_from", "delta"], ["mult_from", "mult"], ["cap_from", "cap"]]: if do_d.has(pair[0]): @@ -178,16 +172,6 @@ func _push_trigger(source: String, id: String, tr: Dictionary, row: Dictionary) "when": when_d, "do": do_d} _triggers.append(t) - # 计数器重置点收集(counter_add/counter_spend 行声明 reset_at) - if do_d.has("counter_id") and String(do_d.get("reset_at", "")) == "round_start": - var cid := String(do_d.counter_id) - if not _reset_on_round_start.has(cid): - _reset_on_round_start.append(cid) - # 寿命域收集(domain=adventure 计数器跨战持久:重建不清零、battle 末导出回冒险账本) - if do_d.has("counter_id") and String(do_d.get("domain", "")) == "adventure": - var aid := String(do_d.counter_id) - if not _adventure_counter_ids.has(aid): - _adventure_counter_ids.append(aid) ## 订阅查询面(发射点缺省行为仲裁用——如 round_end 无 transfer 订阅时走 RAP 转存) @@ -203,74 +187,80 @@ func has_effect_on(event: String, kind: String, mode: String = "") -> bool: ## 事件分发(发射点唯一入口):返回命中效果列表(装载序=声明序;零命中=空数组零扰动)。 -## payload = 事件现场(fact 取值第一优先源);facts = 补充事实面(charge_layers/nest_count 等 -## 运行态读数 Callable——payload 未带时回落)。 -func dispatch(event: String, payload: Dictionary, facts: Callable = Callable()) -> Array: +## ctx = 四桶引用束(引擎不自持状态,计数器读写全经 ctx); +## payload = 事件现场(fact 取值第一优先源);facts = 补充事实面(运行态读数 Callable)。 +func dispatch(ctx: EffectContext, event: String, payload: Dictionary, facts: Callable = Callable()) -> Array: assert(EVENTS.has(event), "[效果引擎] 未知事件: %s(发射点出域)" % event) if event == "round_start": - for cid in _reset_on_round_start: - _counters[cid] = 0 + ctx.round_bucket.clear() # 整桶就地清空(禁 ={} 重赋值断引用;round_ 前缀键集≡旧名单,逐位等价) var hits: Array[Variant] = [] for tr in _triggers: if String(tr.on) != event: continue - if not _when_ok(tr.when, payload, facts): + if not _when_ok(ctx, tr.when, payload, facts): continue hits.append(tr.do) return hits -## 计数器读数(fact counter 与发射点配额面共用) -func counter(counter_id: String) -> int: - return int(_counters.get(counter_id, 0)) +## 计数器归属桶解析(前缀规则唯一出处——round_/lvl_/adv_ 显式桶,其余落 battle 缺省桶)。 +static func bucket_of(ctx: EffectContext, counter_id: String) -> Dictionary[Variant, Variant]: + if counter_id.begins_with("round_"): + return ctx.round_bucket + elif counter_id.begins_with("lvl_"): + return ctx.level_bucket + elif counter_id.begins_with("adv_"): + return ctx.adventure_bucket + return ctx.battle_bucket -func counter_add(counter_id: String, value: int, set_mode: bool = false) -> void: +## counter_id 前缀合法性(加载期校验判定单点):round_/lvl_/adv_ 合法、无前缀落 battle 合法、meta_ 非法 +## (引擎不接存档级);其余未知前缀合法(落 battle——封闭词表方案误伤全部既有 battle id,见卡② §12 裁点②)。 +static func counter_id_legal(counter_id: String) -> bool: + if counter_id.begins_with("meta_"): + return false + return true + + +## 计数器读数(fact counter 与发射点配额面共用——纯查询读 ctx,引擎不自持)。 +static func counter(ctx: EffectContext, counter_id: String) -> int: + return int(bucket_of(ctx, counter_id).get(counter_id, 0)) + + +## 计数器累加/覆写(静态纯函数——写口语义单点,7 施加点共用;算术逐字承自旧实例方法)。 +static func counter_add(ctx: EffectContext, counter_id: String, value: int, set_mode: bool = false) -> void: + var bucket := bucket_of(ctx, counter_id) if set_mode: - _counters[counter_id] = value + bucket[counter_id] = value else: - _counters[counter_id] = int(_counters.get(counter_id, 0)) + value + bucket[counter_id] = int(bucket.get(counter_id, 0)) + value ## 计数器消耗(counter_spend 组合规则——按订阅序消耗共享资源,耗尽即止): ## 返回 true=消耗成功;false=资源不足(调用方按 reason 通道拒绝)。 -func counter_spend(counter_id: String, value: int) -> bool: - var cur := int(_counters.get(counter_id, 0)) +static func counter_spend(ctx: EffectContext, counter_id: String, value: int) -> bool: + var bucket := bucket_of(ctx, counter_id) + var cur := int(bucket.get(counter_id, 0)) if cur < value: return false - _counters[counter_id] = cur - value + bucket[counter_id] = cur - value return true -## adventure 域计数器导出(battle 末调用,快照回冒险账本;仅 domain=adventure 名单内键) -func counters_export() -> Dictionary: - var out := {} - for cid in _adventure_counter_ids: - out[cid] = int(_counters.get(cid, 0)) - return out +# ---- when 判定(条件谓词——零随机全确定;计数器读经 ctx) ---- - -## adventure 域计数器回灌(rebuild 后由发射宿主调用:冒险账本值回填名单内键,缺省 0; -## 名单=本次 rebuild 装载行声明 domain=adventure 的 counter_id 集) -func counters_seed(seed: Dictionary) -> void: - for cid in _adventure_counter_ids: - _counters[cid] = maxi(0, int(seed.get(cid, 0))) - - -# ---- when 判定(条件谓词——零随机全确定) ---- - -func _when_ok(when: Array, payload: Dictionary, facts: Callable) -> bool: +func _when_ok(ctx: EffectContext, when: Array, payload: Dictionary, facts: Callable) -> bool: for c_v in when: - if not _cond_ok(c_v as Dictionary, payload, facts): + if not _cond_ok(ctx, c_v as Dictionary, payload, facts): return false return true -func _cond_ok(c: Dictionary, payload: Dictionary, facts: Callable) -> bool: +func _cond_ok(ctx: EffectContext, c: Dictionary, payload: Dictionary, facts: Callable) -> bool: var fact := String(c.get("fact", "")) var op := String(c.get("op", "eq")) var val = c.get("value", null) - var actual = _fact_value(fact, c, payload, facts) + var actual = _fact_value(ctx, fact, c, payload, facts) match op: "eq": return str(actual) == str(val) @@ -312,17 +302,17 @@ func _cond_ok(c: Dictionary, payload: Dictionary, facts: Callable) -> bool: # 克制矩阵正面判定(matchup = "{attack_type}_vs_{armor}"——矩阵值 > 0 = 克制成立) return _counter_delta_of(String(actual)) > 0 "gte_ref": - return int(actual) >= counter(String(c.get("ref", ""))) + return int(actual) >= counter(ctx, String(c.get("ref", ""))) "lt_ref": - return int(actual) < counter(String(c.get("ref", ""))) + return int(actual) < counter(ctx, String(c.get("ref", ""))) assert(false, "[效果引擎] when 算子出域: %s" % op) return false -func _fact_value(fact: String, c: Dictionary, payload: Dictionary, facts: Callable): +func _fact_value(ctx: EffectContext, fact: String, c: Dictionary, payload: Dictionary, facts: Callable): match fact: "counter": - return counter(String(c.get("id", ""))) + return counter(ctx, String(c.get("id", ""))) _: # fact 取值序:payload 同名字段优先 → 补充事实面(发射点注入的运行态读数) if payload.has(fact): From 96d31705b3ef4c6d505fc86a82c98406499295e4 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 23:02:13 +0800 Subject: [PATCH 31/59] =?UTF-8?q?feat(=E5=8D=A1=E2=91=A1=20T3):=207=20?= =?UTF-8?q?=E6=96=BD=E5=8A=A0=E7=82=B9=20ctx=20=E5=8C=96=20+=20dig=5Fcombo?= =?UTF-8?q?=20=E6=AD=BB=E8=B7=AF=E5=88=A0=E9=99=A4=20+=20run=5Fledger=20?= =?UTF-8?q?=E6=90=AC=E8=BF=90=E9=93=BE=E6=96=B9=E6=B3=95=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - action_economy/damage_controller/reward_economy: dispatch 加 _ctx、写口改 EffectEngine.counter_add/counter(_ctx,...) - battle_orchestrator: _fx_emit→dispatch(counters_ctx)、counter_spend 静态化、删 counters_seed 回灌与 counters_export 战末导出、_feat_yield_adjust 删 dig_combo 死读数与 combo_cap 第五参(零行为差) - grant_segment: counter 读/value_counter/per ctx 化、_apply_counter_hit 写口静态化、combo_cap 收集删除 - run_ledger: 删 counters_seed_snapshot/counters_merge_export + 头注/字段注改 ctx 直写口径 数据行 domain/reset_at 删除与 feats.tres id 改名见 T6;核心层调用面已对齐新 API。 --- game/core/action_economy.gd | 12 ++++++------ game/core/battle_orchestrator.gd | 22 ++++++++-------------- game/core/damage_controller.gd | 8 ++++---- game/core/reward_economy.gd | 2 +- game/core/run_ledger.gd | 18 +++--------------- game/core/settlement/grant_segment.gd | 13 +++++-------- 6 files changed, 27 insertions(+), 48 deletions(-) diff --git a/game/core/action_economy.gd b/game/core/action_economy.gd index a559ad9f..9fef4244 100644 --- a/game/core/action_economy.gd +++ b/game/core/action_economy.gd @@ -102,15 +102,15 @@ func request_dig(chain_size: int, clears_map: bool) -> bool: # mod_eq 闸在行 when〕同面施加) var dig_refund := 0 if _fx != null: - for h in _fx.dispatch("dig_paid", {"ap_cost": cost, "ap_surplus": _ap - cost}): + for h in _fx.dispatch(_ctx, "dig_paid", {"ap_cost": cost, "ap_surplus": _ap - cost}): if String(h.get("kind", "")) == "counter_spend": var extra := int(h.get("value", 1)) if _ap >= cost + extra: cost += extra - _fx.counter_add(String(h.get("counter_id", "")), 1) + EffectEngine.counter_add(_ctx, String(h.get("counter_id", "")), 1) elif String(h.get("kind", "")) == "counter_add": var set_v = h.get("set", null) - _fx.counter_add(String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) + EffectEngine.counter_add(_ctx, String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) elif String(h.get("kind", "")) == "grant_ap": dig_refund += int(h.get("value", 0)) if _ap < cost: @@ -163,12 +163,12 @@ func request_stop() -> bool: # dig_stop 发射+施加(停手挂点〔弃图兑换〕:剩余 AP 随载荷外发,counter_add # value_event="ap_left" 取值面〔值=停手时刻真实余量〕;发射先于记账清零) if _fx != null: - for h in _fx.dispatch("dig_stop", {"ap_left": _ap}): + for h in _fx.dispatch(_ctx, "dig_stop", {"ap_left": _ap}): if String(h.get("kind", "")) == "counter_add": var val := int(h.get("value", 0)) if String(h.get("value_event", "")) == "ap_left": val = _ap - _fx.counter_add(String(h.get("counter_id", "")), val, h.has("set")) + EffectEngine.counter_add(_ctx, String(h.get("counter_id", "")), val, h.has("set")) _last_stop_ap = _ap _ap = 0 _finish_round("stopped", "same_board") @@ -190,7 +190,7 @@ func finish_round_stop(transfer: bool, transfer_pct: int = 100) -> void: var prev_layers := _charge_layers _charge_layers = mini(3, _charge_layers + _last_stop_ap) if _fx != null and _charge_layers >= 3 and prev_layers < 3: - _fx.dispatch("charge_full", {"layers": _charge_layers}) + _fx.dispatch(_ctx, "charge_full", {"layers": _charge_layers}) else: _rap += _last_stop_ap * maxi(1, transfer_pct) / 100 _last_stop_ap = 0 diff --git a/game/core/battle_orchestrator.gd b/game/core/battle_orchestrator.gd index c6814bbd..38c9b0f0 100644 --- a/game/core/battle_orchestrator.gd +++ b/game/core/battle_orchestrator.gd @@ -91,7 +91,7 @@ var counters_ctx: EffectContext = null # 四桶引用束(_ func _fx_emit(event: String, payload: Dictionary) -> Array: if _fx == null: return [] - return _fx.dispatch(event, payload, _fx_fact) + return _fx.dispatch(counters_ctx, event, payload, _fx_fact) # round_start 发射+施加(内容数据驱动扩展批 T3——grant_ap mode:queue=当轮入队,行动经济轮切换 @@ -395,9 +395,8 @@ func begin_battle(enc: Dictionary) -> bool: var tree_rules: Array[Variant] = enc.get("tree_rules", []) as Array # 效果引擎订阅重建(每战从持有集/装备集重建,中途获得下一战生效; # 树规则合成订阅同面装载。装载序=feats 表序→treasure 表序→树规则,写死保种子复放。 - # adventure 域计数器从共享引用回灌〔跨战持久〕) + # 计数器四桶经 counters_ctx 引用宿主容器,无回灌时点(旧 counters_seed 删除)) _fx.rebuild(feat_ids, attunement, tree_rules) - _fx.counters_seed(_ledger.counters_seed_snapshot()) # 秘宝常时参数注入(装配集 kind 分发:远程镐挖距放宽/信标网络封印可达豁免; # 缺省 0/false=零装配零扰动。注入在首板 install 之后〔板在早段〕——板生成不读两参数, # 参数只影响挖掘/插棋动作判据,时序安全) @@ -641,20 +640,16 @@ func _settle() -> void: # ---- 授予段 helpers(极性路由)---- # 开格产出乘区(贪婪矿灯/矿脉直觉/赌徒的血签事件收集器注入): -# positive=power ×(1+静态 mult% + 矿脉直觉连击加成 min(cap,combo)×10%);negative=power ×(1+cost%)。 -# 全零收集器=原快照原样返回(零扰动)。combo 读数=效果引擎 dig_combo 计数器(safe+1/mine 清零, -# 跨轮累计)。 -func _feat_yield_adjust(snap: Dictionary, positive: bool, pos_m: int, neg_m: int, combo_cap: int) -> Dictionary: - var combo_val := _fx.counter("dig_combo") if _fx != null else 0 - if positive and pos_m <= 0 and combo_cap <= 0: +# positive=power ×(1+静态 mult%);negative=power ×(1+cost%)。 +# 全零收集器=原快照原样返回(零扰动)。旧 dig_combo 连击加成死读数(全仓无声明行、combo_val 恒 0)已删——零行为差。 +func _feat_yield_adjust(snap: Dictionary, positive: bool, pos_m: int, neg_m: int) -> Dictionary: + if positive and pos_m <= 0: return snap if not positive and neg_m <= 0: return snap var out: Dictionary[Variant, Variant] = snap.duplicate() var power := int(out.get("power", int(_reward_economy.polarity_row(String(out.get("cell_type", "")), "positive" if positive else "negative").power))) var pct := pos_m if positive else neg_m - if positive and combo_cap > 0: - pct += mini(combo_cap, combo_val) * 10 out["power"] = maxi(1, int(round(float(power) * (1.0 + float(pct) / 100.0)))) return out @@ -721,7 +716,7 @@ func use_treasure(handle: int, target: Vector2i) -> Dictionary: var tu_hits := _fx_emit("treasure_used", {"item_id": String(v.item_id), "target": target}) for h in tu_hits: if String(h.get("kind", "")) == "counter_spend": - if not _fx.counter_spend(String(h.get("counter_id", "")), int(h.get("value", 1))): + if not EffectEngine.counter_spend(counters_ctx, String(h.get("counter_id", "")), int(h.get("value", 1))): var vrow: Dictionary[Variant, Variant] = db.treasure_item_row(String(v.item_id)) var cn_info: int = int(vrow.get("charge_n", 0)) # 读受理行自身 return {"ok": false, "reason": "%s:安全格积点未达(%d/%d)" % [String(vrow.get("display_name", "")), _attune_safe_seen % cn_info if cn_info > 0 else 0, cn_info]} @@ -1129,8 +1124,7 @@ func _battle_over(result: String) -> void: for axis in _fx_bonus_delta.keys(): _ledger.bonus_add_axis(axis, int(_fx_bonus_delta[axis])) _fx_bonus_delta = {"atk": 0, "max_hp": 0, "armor_class": 0, "ap": 0} - if _fx != null: - _ledger.counters_merge_export(_fx.counters_export()) + # 搬运链删除:adventure 桶经 ctx 引用直写 RunLedger,无战末导出时点(旧 counters_export/merge_export) # 映射随战斗结束退役(地图战斗资源 义务④——下一场战斗 = 新板新 scope 批,roll_board 相位守卫的前提) var hero_hp_left := int(_enemy_system.hero_unit().get("hp", 0)) # despawn 前捕获(信号载荷供呈现层"HP 带入下一层") var gp_dropped := _roll_gp_drop() # 战斗掉落(escrow 随此值上抛即弃) diff --git a/game/core/damage_controller.gd b/game/core/damage_controller.gd index 9e4fc7a7..18c0303d 100644 --- a/game/core/damage_controller.gd +++ b/game/core/damage_controller.gd @@ -77,7 +77,7 @@ func set_fx(fx: EffectEngine, ctx: EffectContext) -> void: func _fx_hits(event: String, payload: Dictionary) -> Array: if _fx == null: return [] - return _fx.dispatch(event, payload, _fx_fact) + return _fx.dispatch(_ctx, event, payload, _fx_fact) # 事件发射薄面(免施加观测位——enemy_hp_threshold 等现无订阅者的事件保留零扰动面) @@ -344,13 +344,13 @@ func _hero_attack_base_value(t: Dictionary, ctx: Dictionary) -> float: if String(h.get("kind", "")) == "attack_bonus": var contrib := int(h.get("value", 0)) * _per_value(String(h.get("per", "")), ac_payload) if h.has("value_counter") and String(h.get("value_counter", "")) != "": - contrib = _fx.counter(String(h.get("value_counter", ""))) + contrib = EffectEngine.counter(_ctx, String(h.get("value_counter", ""))) base_value += float(contrib) # 计数器施加(attack_commit 命中行内 counter_add〔用后清零行〕,命中序=声明序) for h in ac_hits: if String(h.get("kind", "")) == "counter_add": var set_v = h.get("set", null) - _fx.counter_add(String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) + EffectEngine.counter_add(_ctx, String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) # 任意真族:厚积薄发满层 spike 倍乘(≥3 层——强制必中已在折扣拍承载) if ctx["spike_ready"]: for h in ac_hits: @@ -463,7 +463,7 @@ func _resolve_enemy_skill(t: Dictionary) -> void: fx_ac_request.call(h) # 石肤 AC 累积归编排器单点(set_hero_ac_override 消费面) "counter_add": var set_v = h.get("set", null) - _fx.counter_add(String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) + EffectEngine.counter_add(_ctx, String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) if shield > 0: total = maxi(int(db.settlement.damage_floor), total - shield) units.apply_damage(hero, total) diff --git a/game/core/reward_economy.gd b/game/core/reward_economy.gd index 71f685cf..a74842af 100644 --- a/game/core/reward_economy.gd +++ b/game/core/reward_economy.gd @@ -64,7 +64,7 @@ func roll_board(eligible: Array) -> bool: # bias_rewards 订阅命中合计=偏运权重加算(行 value_from magnitude 定影);零命中=原行集零扰动) var luck_bias := 0 if _fx != null: - for h in _fx.dispatch("reward_roll", {"polarity": "positive", "cell_count": list.size()}): + for h in _fx.dispatch(_ctx, "reward_roll", {"polarity": "positive", "cell_count": list.size()}): if String(h.get("kind", "")) == "bias_rewards": luck_bias += int(h.get("value", 0)) var cell_rows: Array[Variant] = _biased_cell_rows(luck_bias) # cell 池正向行 weight>0(偏运硬币装配时稀有正向 kinds 权重 +N——池结构零触碰) diff --git a/game/core/run_ledger.gd b/game/core/run_ledger.gd index cad9650e..22899de4 100644 --- a/game/core/run_ledger.gd +++ b/game/core/run_ledger.gd @@ -4,12 +4,12 @@ extends RefCounted # 可写」收口 = 单类持四账)。 # 所有权:AdventureRunner 持有(开局构造、冒险全程唯一宿主);LevelRunner 经 set_run_ledger # 下传并装配 encounter;战斗侧(BattleOrchestrator)经 encounter["ledger"] 拿本类引用, -# 只走下方 read/append 原语——战末 export/开局 seed 时点语义不变(确定性设计原样保留, -# 只把「函数签名上不可见的共享可变引用」换成签名可见的显式类)。 +# 只走下方 read/append 原语;adventure 桶经 EffectContext 引用被效果引擎就地直写(无战末 export/ +# 开局 seed 搬运时点——跨战持久=同一字典引用,随本类生灭)。 var attune_charges: Dictionary[Variant, Variant] = {} # 同调主动件充能账(use_treasure 扣减;断点随局回档) var vision_counter: Dictionary[Variant, Variant] = {} # 真视类使用计数(冒险开始置 {"used":0}; # 缺省空 = 调试/单场战斗不计——enc 缺键守卫语义) -var adventure_counters: Dictionary[Variant, Variant] = {} # adventure 域效果计数器(rebuild 回灌/战末导出回写目标) +var adventure_counters: Dictionary[Variant, Variant] = {} # adventure 桶(adv_ 前缀计数器;经 EffectContext 引用被引擎就地直写、跨战持久随本类生灭) var bonus: Dictionary[Variant, Variant] = {} # 统一冒险加算区(冒险开始置四轴零账——商店购买/三选一属性件/战末 bonus_delta 汇入) @@ -33,18 +33,6 @@ func vision_count_add(n: int) -> void: vision_counter["used"] = int(vision_counter.get("used", 0)) + n -func counters_seed_snapshot() -> Dictionary: - return adventure_counters # 回灌读面(时点 = begin_battle rebuild 后——语义不变) - - -func counters_merge_export(exported: Dictionary) -> void: - # 战末回写(原编排器逐字语义:仅非空账参与、逐键覆写) - if adventure_counters.is_empty(): - return - for cid in exported.keys(): - adventure_counters[cid] = int(exported[cid]) - - func bonus_add_axis(axis: String, delta: int) -> void: # 原编排器战末汇入逐字语义(has 闸——账外轴丢弃) if bonus.has(axis): diff --git a/game/core/settlement/grant_segment.gd b/game/core/settlement/grant_segment.gd index 59a0bc30..39356838 100644 --- a/game/core/settlement/grant_segment.gd +++ b/game/core/settlement/grant_segment.gd @@ -51,15 +51,12 @@ func run(ri: int) -> void: "new_resource_type": is_new_type}) var pos_m := 0 var neg_m := 0 - var combo_cap := -1 for h in dr_hits: if String(h.get("kind", "")) != "yield_mult": continue pos_m += int(h.get("mult", 0)) neg_m += int(h.get("cost_mult", 0)) - if int(h.get("cap", 0)) > 0: - combo_cap = int(h.cap) # 矿脉直觉连击上限 - oc._grant_routed(oc._feat_yield_adjust(snap, true, pos_m, neg_m, combo_cap), "positive", "safe_cell", evt.cell, ri, "") + oc._grant_routed(oc._feat_yield_adjust(snap, true, pos_m, neg_m), "positive", "safe_cell", evt.cell, ri, "") # 计数器执行(连击计数——加法族,乘区收集后执行=本格兑付用旧值,与迁移前逐位一致) for h in dr_hits: if String(h.get("kind", "")) == "counter_add": @@ -100,7 +97,7 @@ func run(ri: int) -> void: halve_pct += int(h.get("value", 0)) "damage_reduce": if h.has("value_counter") and String(h.get("value_counter", "")) != "": - mine_reduce += oc._fx.counter(String(h.get("value_counter", ""))) # 安全帽——层值减免 + mine_reduce += EffectEngine.counter(oc.counters_ctx, String(h.get("value_counter", ""))) # 安全帽——层值减免 else: mine_reduce += int(h.get("value", 0)) # 背水——定值减免 "heal": @@ -122,7 +119,7 @@ func run(ri: int) -> void: _apply_counter_hit(h) if not oc._hits_of(mh_hits, "reveal_tiles").is_empty(): oc._fx_enqueue_reveal() # 见血开窍——每颗雷一次揭示(授予段末统一兑付) - oc._grant_routed(oc._feat_yield_adjust(snap, false, 0, 0, -1), "negative", "mine_hit", evt.cell, ri, "", "", halve_pct) + oc._grant_routed(oc._feat_yield_adjust(snap, false, 0, 0), "negative", "mine_hit", evt.cell, ri, "", "", halve_pct) for h in mh_hits: if String(h.get("kind", "")) == "open_ticket" and String(h.get("channel", "")) == "reflect": var nct := oc._damage.open_ticket(DamageController.KIND_BOARD_BLAST, "attune_nest_counter", "惊巢反制·反弹", "board", @@ -202,7 +199,7 @@ func run(ri: int) -> void: var re_fx := oc._fx_emit("round_end", {"round": ri}) for h in re_fx: if String(h.get("kind", "")) == "open_ticket" and String(h.get("channel", "")) == "blast": - var mg_layers := oc._fx.counter(String(h.get("per", ""))) + var mg_layers := EffectEngine.counter(oc.counters_ctx, String(h.get("per", ""))) var mg_total := int(h.get("value", 0)) * mg_layers if mg_total > 0: # source_class 用中性名;per-counter 反打通道保留泛用面 @@ -322,7 +319,7 @@ func _judge_seal(evt: Dictionary, ri: int) -> void: # counter_add 三行组单点(原五位分支本体逐字收拢——kind 分派随段归位 P1-1) func _apply_counter_hit(h: Dictionary) -> void: var set_v = h.get("set", null) - oc._fx.counter_add(String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) + EffectEngine.counter_add(oc.counters_ctx, String(h.get("counter_id", "")), int(h.get("value", 0)) if set_v == null else int(set_v), set_v != null) # grant_material 兑付块单点(原三位分支本体逐字收拢——source_class 两态 safe_cell/seal_hit 由参承载) From 7f45f90484a7fce31f5b80a4e0e7ab48158a8bbe Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 23:04:16 +0800 Subject: [PATCH 32/59] =?UTF-8?q?feat(=E5=8D=A1=E2=91=A1=20T6):=20feats.tr?= =?UTF-8?q?es=20counter=5Fid=20=E6=94=B9=E5=90=8D=20+=20domain/reset=5Fat?= =?UTF-8?q?=20=E9=94=AE=E5=88=A0=E9=99=A4=20+=20DO=5FKEYS=20=E6=94=B6?= =?UTF-8?q?=E7=BC=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - twin_digs→adv_twin_digs、instinct_atk→round_instinct_atk(写点+读点 value_counter 成对改) - 删 9 处 domain/reset_at 键行(含 pain_layers 三处归 battle、insurance_used domain=battle 删键) - 引擎 DO_KEYS 删 domain/reset_at;do 键白名单注释改前缀归属口径 config_db_test 26 checks 全绿(feats.tres 加载校验通过、跨表护栏零违例)。 --- game/core/effect_engine.gd | 6 +++--- game/data/tables/feats.tres | 35 +++++++++++++---------------------- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/game/core/effect_engine.gd b/game/core/effect_engine.gd index 6b37cf99..4ce6d5e4 100644 --- a/game/core/effect_engine.gd +++ b/game/core/effect_engine.gd @@ -67,12 +67,12 @@ const WHEN_KEYS := ["fact", "op", "value", "id", "ref", "value_from"] ## do 效果键白名单(trigger 行 do 字典键——零裸 flat 同族护栏:kind 外键全部参数引用面。 ## value_event=事件载荷取值键名〔爆破会计——counter_add 值=本轮挖格花费 ## payload.ap_cost〕;value_counter=计数器取值键〔疼痛记忆/弃图兑换——attack rider 值=账面层值〕; -## domain=计数器寿命域〔battle=战斗域重建清零〔缺省〕/adventure=跨战持久随 battle 末导出〕; +## 归属由 counter_id 前缀表达(round_/lvl_/adv_/无前缀=battle),旧 domain/reset_at 键删除; ## axis=bonus_delta 加算区轴向) const DO_KEYS := ["kind", "value", "value_from", "delta", "delta_from", "mult", "mult_from", "cap", "cap_from", "cost_mult", "per", "divisor", "dtype", "mode", "channel", "counter_id", - "reset_at", "set", "status_id", "label", "fallback", "target_kinds", "trade_atk", "trade_hit", - "value_event", "value_counter", "domain", "axis"] + "set", "status_id", "label", "fallback", "target_kinds", "trade_atk", "trade_hit", + "value_event", "value_counter", "axis"] ## 主动件分发通道(不经事件订阅——刷新/显影/移除是玩家主动动作;use_treasure 按 kind 分发) ## safe_dig 安全格直开(天眼——3×3 内安全格按普通挖格规则全额兑付 diff --git a/game/data/tables/feats.tres b/game/data/tables/feats.tres index 67e649fb..4cb5cd5c 100644 --- a/game/data/tables/feats.tres +++ b/game/data/tables/feats.tres @@ -26,9 +26,8 @@ rows = [ "on": "dig_paid", "do": { "kind": "counter_add", - "counter_id": "twin_digs", - "value": 1, - "domain": "adventure" + "counter_id": "adv_twin_digs", + "value": 1 } }, { @@ -36,7 +35,7 @@ rows = [ "when": [ { "fact": "counter", - "id": "twin_digs", + "id": "adv_twin_digs", "op": "mod_eq", "value": 2, "ref": 1 @@ -208,8 +207,7 @@ rows = [ "kind": "counter_add", "counter_id": "round_blast_spent", "value": 1, - "value_event": "ap_cost", - "reset_at": "round_start" + "value_event": "ap_cost" } }, { @@ -373,8 +371,7 @@ rows = [ "do": { "kind": "counter_add", "counter_id": "pain_layers", - "value": 1, - "domain": "adventure" + "value": 1 } }, { @@ -489,16 +486,15 @@ rows = [ "on": "mine_hit", "do": { "kind": "counter_add", - "counter_id": "instinct_atk", - "value": 2, - "reset_at": "round_start" + "counter_id": "round_instinct_atk", + "value": 2 } }, { "on": "attack_commit", "do": { "kind": "attack_bonus", - "value_counter": "instinct_atk" + "value_counter": "round_instinct_atk" } } ] @@ -514,8 +510,7 @@ rows = [ "do": { "kind": "counter_add", "counter_id": "round_mines", - "value": 1, - "reset_at": "round_start" + "value": 1 } }, { @@ -531,8 +526,7 @@ rows = [ "do": { "kind": "counter_add", "counter_id": "pain_layers", - "value": 1, - "domain": "adventure" + "value": 1 } } ] @@ -624,8 +618,7 @@ rows = [ "do": { "kind": "counter_add", "counter_id": "pain_layers", - "value": 1, - "domain": "adventure" + "value": 1 } } ] @@ -719,8 +712,7 @@ rows = [ "do": { "kind": "counter_add", "counter_id": "round_digs", - "value": 1, - "reset_at": "round_start" + "value": 1 } }, { @@ -873,8 +865,7 @@ rows = [ "do": { "kind": "forgive_seal_miss", "counter_id": "insurance_used", - "value": 1, - "domain": "battle" + "value": 1 } } ] From d402ea143aed0cc0c48b22311f533a306c090f28 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 23:05:39 +0800 Subject: [PATCH 33/59] =?UTF-8?q?feat(=E5=8D=A1=E2=91=A1=20T5-=E9=83=A8?= =?UTF-8?q?=E5=88=86):=20validate=5Ftrigger=5Frow=20=E5=A2=9E=20counter=5F?= =?UTF-8?q?id=20=E5=89=8D=E7=BC=80=E5=90=88=E6=B3=95=E6=80=A7=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=EF=BC=88.tres=20=E8=A1=8C=E5=8A=A0=E8=BD=BD=E8=87=B4?= =?UTF-8?q?=E5=91=BD=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 判据单点 counter_id_legal(与 _push_trigger assert 同源,无第二份前缀表);meta_ 出域→errs→加载致命。 feat_vouchers 26 checks 在 ctx 化引擎下全绿(保险 V25 + 卡① A10–A12 未破,契约 5)。 引用闭合校验 + 负面套件 + manifest 归 T5 续(下一轮)。 --- game/core/effect_engine.gd | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/game/core/effect_engine.gd b/game/core/effect_engine.gd index 4ce6d5e4..0883c8f4 100644 --- a/game/core/effect_engine.gd +++ b/game/core/effect_engine.gd @@ -367,6 +367,11 @@ static func validate_trigger_row(rid: String, row: Dictionary, triggers: Array, var kind := String(do_d.get("kind", "")) if not EFFECT_KINDS.has(kind): errs.append({"category": "enum", "message": "%s 效果类型出域(解释器闭集): %s" % [rid, kind]}) + # 计数器前缀归属合法性(.tres 行路径——写错前缀加载致命;判据单点 counter_id_legal,与 _push_trigger 同源) + if do_d.has("counter_id"): + var cid := String(do_d.counter_id) + if not counter_id_legal(cid): + errs.append({"category": "enum", "message": "%s counter_id 前缀非法(meta_ 出域/引擎不接存档级): %s" % [rid, cid]}) # value_from/delta_from/mult_from/cap_from 引用面:行字段存在性(悬空=加载致命)—— # do 与 when 两侧同面(when value_from=dawn_order effective_rounds 先例) for vf_k in ["value_from", "delta_from", "mult_from", "cap_from"]: From 4c5bdbc9aa96f255340f560f95085bc823c601ec Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 23:12:29 +0800 Subject: [PATCH 34/59] =?UTF-8?q?feat(=E5=8D=A1=E2=91=A1=20T5):=20?= =?UTF-8?q?=E8=AE=A1=E6=95=B0=E5=99=A8=E5=BC=95=E7=94=A8=E9=97=AD=E5=90=88?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=20+=20V9=20=E8=B4=9F=E9=9D=A2=E5=A5=97?= =?UTF-8?q?=E4=BB=B6=20+=20manifest=20=E7=99=BB=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - config_db_cross_validator ⑦ 引用闭合:声明集=feats+treasure 各行 do.counter_id, 读点(when counter id / value_counter / counter_spend counter_id)无同名写入行→加载致命 (判据只做成员判定,不重写前缀规则——契约 6 两落点同源) - 新建 counter_prefix_fatal_test.gd(expect1/negative):①meta_ 非法前缀②悬空读点两断言,均正确拒绝 - run_all.gd manifest 登记负面套件 real 数据 config_db_test 26 全绿(闭合零误伤);insurance_used 经 forgive_seal_miss 行 do.counter_id 声明纳入。 --- game/core/config_db_cross_validator.gd | 34 +++++++++ game/tests/run_all.gd | 1 + .../data_config/counter_prefix_fatal_test.gd | 71 +++++++++++++++++++ .../counter_prefix_fatal_test.gd.uid | 1 + 4 files changed, 107 insertions(+) create mode 100644 game/tests/unit/data_config/counter_prefix_fatal_test.gd create mode 100644 game/tests/unit/data_config/counter_prefix_fatal_test.gd.uid diff --git a/game/core/config_db_cross_validator.gd b/game/core/config_db_cross_validator.gd index 7ba5f18e..f1bc4a79 100644 --- a/game/core/config_db_cross_validator.gd +++ b/game/core/config_db_cross_validator.gd @@ -109,6 +109,40 @@ func cross_validate(loaded: Dictionary, push_diag: Callable) -> void: if quota < 1: push_diag.call("error", "shelf_zero_quota", "ShopTable.pool_shelf kind %s 令牌配额为 0(牌库空种入货架 = 库存无锚)" % kind) + # ⑦ 计数器引用闭合(卡② V9——读点 id 必命中同名写入行,否则加载致命): + # 声明集 = feats + treasure 各行 triggers 内 kind=counter_add 的 do.counter_id; + # 读点 = when fact=counter 的 id、do.value_counter、kind=counter_spend 的 counter_id。 + var feats_tab = loaded.get("feats") + var trig_rows: Array = [] + if feats_tab != null: + for r in feats_tab.rows: + trig_rows.append(r) + if treasure_tab != null: + for r in treasure_tab.rows: + trig_rows.append(r) + var counter_decls := {} + for row in trig_rows: + for tr_v in (row.get("triggers", []) as Array): + var dd: Dictionary = (tr_v as Dictionary).get("do", {}) as Dictionary + # 声明集=任一 do.counter_id 行(counter_add 直写、forgive_seal_miss 经 _apply_counter_hit 写——皆写入行) + if dd.has("counter_id"): + counter_decls[String(dd.counter_id)] = true + for row in trig_rows: + var rid := String(row.get("feat_id", row.get("item_id", ""))) + for tr_v in (row.get("triggers", []) as Array): + var tr: Dictionary = tr_v as Dictionary + for c_v in (tr.get("when", []) as Array): + var c: Dictionary = c_v as Dictionary + if String(c.get("fact", "")) == "counter" and c.has("id"): + var rd := String(c.id) + if not counter_decls.has(rd): + push_diag.call("error", "counter_dangling_ref", "%s when counter 读点无同名写入行: %s(引用闭合)" % [rid, rd]) + var do2: Dictionary = tr.get("do", {}) as Dictionary + if do2.has("value_counter") and not counter_decls.has(String(do2.value_counter)): + push_diag.call("error", "counter_dangling_ref", "%s value_counter 读点无同名写入行: %s" % [rid, String(do2.value_counter)]) + if String(do2.get("kind", "")) == "counter_spend" and do2.has("counter_id") and not counter_decls.has(String(do2.counter_id)): + push_diag.call("error", "counter_dangling_ref", "%s counter_spend 无同名写入行: %s" % [rid, String(do2.counter_id)]) + # 池模板 × 技能行跨表校验(加载期致命;返回错误列表——ConfigDB 诊断通道与冒烟直验共用): # skill_id 悬空致命 + 池构成纪律(每池恰一行普攻、增益技 ≤1、妨害技 ≤1——proposal §2.1 结构保证 + diff --git a/game/tests/run_all.gd b/game/tests/run_all.gd index 7e9113e0..9f282a4c 100644 --- a/game/tests/run_all.gd +++ b/game/tests/run_all.gd @@ -46,6 +46,7 @@ func _suites() -> Array: # negative=true=负面套件:坏表/违规输入是它的测试目标,输出里必然带 Parse Error, # 脚本错误扫描对它属误伤——豁免只放行这一件,且仅限「错误扫描」一闸(退出码与断言下限照判)。 {"path": "res://tests/unit/data_config/reward_dangling_treasure_test.gd", "expect": 1, "negative": true}, # 秘宝双表校验 + {"path": "res://tests/unit/data_config/counter_prefix_fatal_test.gd", "expect": 1, "negative": true}, # 卡② V9 前缀合法性+引用闭合加载致命 {"path": "res://tests/unit/data_config/rng_service_test.gd", "expect": 0}, {"path": "res://tests/unit/core/treasure_items_test.gd", "expect": 0}, # 秘宝结构冻结断言面 {"path": "res://tests/unit/core/breakpoint_resume_test.gd", "expect": 0}, # 断点往返/续玩确定性/幂等/退出清断点 diff --git a/game/tests/unit/data_config/counter_prefix_fatal_test.gd b/game/tests/unit/data_config/counter_prefix_fatal_test.gd new file mode 100644 index 00000000..f5289ec2 --- /dev/null +++ b/game/tests/unit/data_config/counter_prefix_fatal_test.gd @@ -0,0 +1,71 @@ +# 致命类用例(独立进程,期望退出码 1) +# 卡② V9/E1——计数器前缀合法性 + 引用闭合加载期致命双断言: +# ①向 feats.tres 注入 kind=counter_add 但 counter_id 前缀非法(meta_ 出域)的行 → validate_trigger_row 须拦; +# ②注入读点(when fact=counter id)指向无同名写入行的悬空 id → config_db_cross_validator 引用闭合须拦。 +# 任一违规被放行即回归(退出码 2)。两夹具目录各跑一次 load_tables,均须拒绝。 +# 运行:godot --headless --path game --script res://tests/unit/data_config/counter_prefix_fatal_test.gd +extends SceneTree + +const ConfigDBScript := preload("res://core/config_db.gd") +const Kit := preload("res://tests/unit/test_kit.gd") + +const SRC_DIR := "res://data/tables" +const BAD_PREFIX_DIR := "user://counter_fixture_prefix" +const BAD_REF_DIR := "user://counter_fixture_ref" + +# 注入探针:非法前缀写入行(meta_probe 无 meta_ 合法归桶 → counter_id_legal false) +const PROBE_PREFIX := ' {\n "feat_id": "prefix_probe",\n "display_name": "前缀探针",\n "rarity": "common",\n "triggers": [ { "on": "dig_reveal", "when": [], "do": { "kind": "counter_add", "counter_id": "meta_probe", "value": 1 } } ],\n "desc": "夹具探针——非法前缀"\n},\n' +# 注入探针:悬空读点(when counter id=pain_layer 单数,全表无同名写入行 → 引用闭合拦) +const PROBE_REF := ' {\n "feat_id": "ref_probe",\n "display_name": "引用探针",\n "rarity": "common",\n "triggers": [ { "on": "dig_reveal", "when": [ { "fact": "counter", "id": "pain_layer", "op": "lt", "value": 1 } ], "do": { "kind": "grant_ap", "mode": "queue", "value": 1 } } ],\n "desc": "夹具探针——悬空读点"\n},\n' + + +func _inject(dir: String, probe: String) -> bool: + var path := dir + "/feats.tres" + var f := FileAccess.open(path, FileAccess.READ) + if f == null: + push_error("注入失败:读不到 %s" % path) + return false + var s := f.get_as_text() + f.close() + var anchor := "rows = [" + var idx := s.find(anchor) + if idx < 0: + push_error("注入失败:锚点 '%s' 未找到(len=%d)" % [anchor, s.length()]) + return false + var cut := idx + anchor.length() + s = s.substr(0, cut) + "\n" + probe + s.substr(cut) + var w := FileAccess.open(path, FileAccess.WRITE) + if w == null: + push_error("注入失败:写不开 %s" % path) + return false + w.store_string(s) + w.close() + return true + + +func _assert_rejected(bad_dir: String, probe: String, label: String) -> bool: + # 返回 true=正确拒绝;false=放行或夹具失败(调用方据此退出 2) + if not Kit.copy_tables(SRC_DIR, bad_dir) or not _inject(bad_dir, probe): + push_error("[%s] 夹具目录准备失败" % label) + return false + var db = ConfigDBScript.new() + var ok: bool = db.load_tables(bad_dir, false) + if ok: + push_error("[%s] 违规表被放行——加载期校验失守(回归)" % label) + return false + if db.diagnostics_count("error") < 1: + push_error("[%s] 加载被拒但零 error 诊断——校验通道静默化(回归)" % label) + return false + print("[%s] 正确拒绝(error 诊断在案)" % label) + return true + + +func _init() -> void: + if not _assert_rejected(BAD_PREFIX_DIR, PROBE_PREFIX, "counter_prefix_fatal_test/①非法前缀"): + quit(2) + return + if not _assert_rejected(BAD_REF_DIR, PROBE_REF, "counter_prefix_fatal_test/②悬空读点"): + quit(2) + return + print("[counter_prefix_fatal_test] 双断言均正确拒绝(前缀合法性 + 引用闭合)") + quit(1) diff --git a/game/tests/unit/data_config/counter_prefix_fatal_test.gd.uid b/game/tests/unit/data_config/counter_prefix_fatal_test.gd.uid new file mode 100644 index 00000000..1a1ee1ff --- /dev/null +++ b/game/tests/unit/data_config/counter_prefix_fatal_test.gd.uid @@ -0,0 +1 @@ +uid://ckn8u3rt64qmi From 811f9880323186b7c7e81f0625e863d795a0b5ae Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 23:15:05 +0800 Subject: [PATCH 35/59] =?UTF-8?q?rules(=E8=A7=84=E5=88=99=E5=AE=A1?= =?UTF-8?q?=E9=98=85=E8=90=BD=E5=9C=B0=E6=89=B9):=20=E5=8D=81=E6=9D=A1?= =?UTF-8?q?=E8=AF=84=E5=AE=A1=E6=84=8F=E8=A7=81=E8=90=BD=E5=9C=B0=E2=80=94?= =?UTF-8?q?=E2=80=94=E5=91=88=E6=8A=A5=E5=9B=9B=E9=97=AE/=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=A4=B4=E7=BC=A9=E7=AA=84/=E7=A6=81=E8=AF=8D?= =?UTF-8?q?=E8=A1=A8=E5=86=BB=E7=BB=93/lean=E6=AD=BB=E6=9D=A1=E6=96=87?= =?UTF-8?q?=E9=80=80=E5=BD=B9/=E6=97=A5=E6=9C=9F=E6=89=B9=E6=B3=A8?= =?UTF-8?q?=E6=B8=85=E9=99=A4/AGENTS=E7=98=A6=E8=BA=AB/=E5=88=86=E5=9F=9F?= =?UTF-8?q?=E9=97=B8=E5=8F=A3=E5=BE=84/=E7=8A=B6=E6=80=81=E6=A0=8F?= =?UTF-8?q?=E7=BA=AF=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AGENTS.md: 呈报六问改读后自检四问;文件头红线删行数上限与白名单;日期批注清除;回执五况细则挪 process-conventions §3.10;流水线闸过时状态句改事实句 - process-conventions: §1.2 非迭代批改按改动域跑闸;§3.10 承接五况;两处日期批注清除;§2 表格凭据落点改现状清单 - code-conventions: §1.4.1 重写(删 8 行上限/两类白名单/90 文件清偿义务);§2.1 联动;两处日期批注清除 - test-conventions: 三处日期批注清除(三处实证日期属证据保留) - doc-conventions: §1 lean 死条文删除;§4 词表冻结条款;§12.1 重写(状态行只写状态词;现状=关联文档清单;删括号凭据全部条款);三处日期批注清除;§5 重复词修复 - 术语表: 用语规范节加词表冻结句 - 06-待办清单: 11 条带括号状态行迁移(括号证据移入现状关联文档清单;待裁决说明并入现状;每条状态行只留状态词) - tools/audit_file_headers.py: 删 R1 行数上限(R0 载体/R2 日期/R3 变更叙事保留) - tools/gdd_lint.py: R2 表格占比判据与 R2_EXEMPT 整体退役(lean 解读对象已亡,只产存量噪音) - tools/doc_term_audit.py: 词表冻结注释 - tools/pipeline_gate.py: 状态栏括号凭据核对废止,新增状态行禁括号判据(点名病因短路);闭合证据改现状正文核对(卡片路径磁盘存在性+交叉核、文档路径+版本、art-bible+版本) - game/tests/static_scan.sh: S10 注释同步 变异验证(test-conventions §6):pipeline_gate 注入括号→状态行含括号内容红 exit1;删正文卡片路径→正文缺卡片路径+交叉核红 exit1;audit_file_headers 注入变更叙事→R2/R3 红 exit1、头注 12 行纯说明→0 红(上限停用实证)。坑册新增:未提交工作区禁 git checkout 变异还原(会连带回滚在途改动),须备份文件法。 全批净变化 +155/−146(12 文件)。 --- AGENTS.md | 12 +-- design/engineering/code-conventions.md | 18 ++-- design/engineering/doc-conventions.md | 35 ++++--- design/engineering/process-conventions.md | 14 +-- design/engineering/test-conventions.md | 6 +- design/gdd/06-待办清单.md | 50 ++++++---- design/gdd/术语表.md | 2 +- game/tests/static_scan.sh | 4 +- tools/audit_file_headers.py | 10 +- tools/doc_term_audit.py | 2 + tools/gdd_lint.py | 36 ++----- tools/pipeline_gate.py | 112 ++++++++++++++-------- 12 files changed, 155 insertions(+), 146 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 84dfeef5..93970c43 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,7 +16,7 @@ ## 运行与验证(工作目录 = 含 project.godot 的切片目录) -- **交付前验收 = 跑 `tools/run_all_gates.sh`,按本批改动域选档(`--code` 只跑代码域/`--docs` 只跑文档域/不带参数=两域全量),所选域全绿才合回 master**——它是全部验证闸的唯一入口与唯一清单,**域划分也只写在它这一个地方**,闸件增减与分域调整都只改它,文档禁另列清单。一次改动同批混触 `game/` 与文档面时跑全量档。跑完写回执 `game/tests/.gates/receipt.json`(含 `domain` 字段),合回时由 worktree-guard 按 diff 路径推出该验哪个域再校验回执(缺回执/quick 模式/回执 commit ≠ HEAD/域不覆盖本次改动/含新增红,五况一律拦截) +- **交付前验收 = 跑 `tools/run_all_gates.sh`,按本批改动域选档(`--code` 只跑代码域/`--docs` 只跑文档域/不带参数=两域全量),所选域全绿才合回 master**——它是全部验证闸的唯一入口与唯一清单,**域划分也只写在它这一个地方**,闸件增减与分域调整都只改它,文档禁另列清单。一次改动同批混触 `game/` 与文档面时跑全量档。跑完写回执 `game/tests/.gates/receipt.json`(含 `domain` 字段),合回时由 worktree-guard 按 diff 路径推出该验哪个域再校验回执(五况拦截细则见 process-conventions §3.10) - 单件直跑(调试期最窄确认用,**不构成验收**):系统级断言面 `python tools/run_smoke.py`(名带 smoke 但不止存活检查,术语见 `game/tests/README.md`)· 场景探针 `…console.exe --headless --path . res://smoke/ui_probe.tscn` · 单元 `… --script res://tests/run_all.gd` - 调参批量:`--script res://smoke/adventure_monte_carlo.gd`(全冒险期望)· `res://smoke/reward_expectation.gd`(奖励期望);通关率/难度类测量一律走全冒险 - 数值验证:`python tools/balance_verifier.py`(采集端 `res://smoke/verifier_batch.gd`,报告与原始数据落 `sim-data/`) @@ -33,7 +33,7 @@ - `sim-data/` — 机器读数据产物;数据件不入 git(入库例外 = README+analyze.py+growth_model.py);MC 锚与读数常驻留盘,无数值调整禁重跑 - `tools/` — python 工具脚本;`archive/` — 收口归档 zip(gitignored) - `reports/` — 过程件容器:**需求卡片**(写卡段产出,实现批的输入合同)+迭代批产出物(实现报告/代拍板追认单/GDD 反哺点清单);**实现批唯一可写目录**,只放 .md,不是事实源(细则见 `reports/README.md`) -- 根目录:`README.md`(纯指路牌:设计/流程/当前位/待办四个链接,零规则重述)、`roadmap.md`(里程碑+迭代总表六列+顶部「当前位」节=现在做什么)、`stage.txt`/`review-mode.txt`(运行开关);仓库根禁止再设会话状态文件(2026-10-18 用户裁,细则见 doc-conventions 第 10 节) +- 根目录:`README.md`(纯指路牌:设计/流程/当前位/待办四个链接,零规则重述)、`roadmap.md`(里程碑+迭代总表六列+顶部「当前位」节=现在做什么)、`stage.txt`/`review-mode.txt`(运行开关);仓库根禁止再设会话状态文件(细则见 doc-conventions 第 10 节) ## 规范导航(动手前先查表) @@ -53,20 +53,20 @@ ## 硬性红线(勿违反;操作细则在 process-conventions.md 与各规约) - 主工作区禁止直接改动与提交——一切改动走独立 worktree(豁免:`.zcode/` 与 `.qoder/` 两份本机 harness 配置,实测均不入 git) -- **仓库根禁止设会话状态文件**(2026-10-18 用户裁废除 `active.md`)——现状看 roadmap「当前位」,待办看 06,过程看 git 提交信息,产出物看 `reports/`;任何文档禁止另设「当前状态快照」节,两处记同一件事必然漂移(细则见 doc-conventions 第 10 节) +- **仓库根禁止设会话状态文件**(`active.md` 已废除)——现状看 roadmap「当前位」,待办看 06,过程看 git 提交信息,产出物看 `reports/`;任何文档禁止另设「当前状态快照」节,两处记同一件事必然漂移(细则见 doc-conventions 第 10 节) - 测试执行两入口铁规——只有迭代 loop 开发与用户点名两个触发入口;其余会话零测试,需测试支撑先请示并注明未跑测 - 交付前验收 = 跑 `tools/run_all_gates.sh` **按改动域**全绿(唯一入口、唯一闸清单、唯一域划分,禁在文档另列);合回 master 由 worktree-guard 按 diff 推域校验回执强制(process-conventions §3) - **两类批**——**迭代批**(代码实现,`/iter` 发射):**禁写 `design/` 整个目录**(含新增/修改/删除),设计文档对它只读、是写测试与实现代码的输入依据;产出物只准写 `reports/`;批末只跑代码域闸。**非迭代批**(工具/规则/文档改动):不占 roadmap 迭代号,按改动域跑闸。文档内容的落地走五段流水线相应段(文档设计段入口=doc-design 技能;登记条目格式由流水线闸强制) -- 五段流水线铁律——一切工作按「登记 → 文档设计/美术设计 → 写需求卡片 → 迭代编排 → 实现」推进,段间不自动流转、每段转进由用户发令;编入迭代的卡片必须设计闭合+零待裁点,流水线闸 `tools/pipeline_gate.py` 强制(工具并行开发中,注册进 run_all_gates.sh 文档域归第二批);实现段零裁断——卡片没写清=上游缺陷,停该卡退回上游,禁内联求裁(process-conventions §2,格式与状态机=doc-conventions §12) +- 五段流水线铁律——一切工作按「登记 → 文档设计/美术设计 → 写需求卡片 → 迭代编排 → 实现」推进,段间不自动流转、每段转进由用户发令;编入迭代的卡片必须设计闭合+零待裁点,流水线闸 `tools/pipeline_gate.py` 强制(已注册进 run_all_gates.sh 文档域);实现段零裁断——卡片没写清=上游缺陷,停该卡退回上游,禁内联求裁(process-conventions §2,格式与状态机=doc-conventions §12) - MC/模拟:无数值改动零跑;档位硬闸见 `sim-data/README.md`「MC 采集档位表」,一档只能由用户发起 - 闸机轮次纪律:新码先孤立验证 → 出红只跑红件最小单元 → 长批先最小参数试车 → 开工扫坑册(process-conventions §6) - 变异验证——新增/改写验收函数必须变异变红才算验收成立;无变异红记录只写「已实现,拦截能力未证」(test-conventions §6) - 中间产物吸收即死——结论先吸收进权威文档、未决先迁 06,文件即删且永不提交(doc-conventions 第 11 节) - **禁写变更记录**——文档与代码文件内一律禁设「版本历史/修订记录/变更记录/修改记录/更新记录/更新日志」节或表格,禁写「本版改了哪些条款」式逐版本叙述与 `# 2026-xx-xx 缺陷修批——` 式行内修订注记;沿革只进 git commit log。版本号可作文档现行身份标记留在文首状态行与正文引用中(doc-conventions 第 5 节,机检闸 gdd_lint R4 反转拦截) - 用语红线——一切对用户输出禁自造黑话,需要作者解释的词必须展开成完整白话句(doc-conventions 第 4 节三形态表) -- 呈报六问——What 现状差异 / Why 动机与不做代价 / How 方案与全部备选 / Where 影响面 / 验收判据 / 不确定点单列收尾;Who/When 不进正文;仅首次描述需求/bug/方案适用 +- 呈报四问(读后自检制)——向用户首次完整呈报一件事(需求/缺陷/方案/结论)时,写完先自查:读者只读这一段,能否不看原文答出——① 现状差在哪:现在是什么、缺什么;② 你建议做什么:做完预期什么效果、会动到哪些面;③ 为什么选这个做法:考虑过、放弃过哪些别的路;④ 做完怎么验证:哪些还有把握不足。哪问答不出就补哪问,禁靠加小标题凑数;三句话能说清的小件合并为三句:现状一句、建议与验证一句、没把握的一句;后续追问与推进不必重跑全框架 - 真人检测只登记不阻塞——登记进 07 清单/实现报告即完成义务,禁以等目检为停工理由或收口前置 -- 文件头 = `##` 文档注释,介绍本模块,≤8 行两类白名单(①职责摘要 ②使用约束;禁一切文档反向链接;code-conventions §1.4.1,规范权威 = Google pyguide §3.8 + PEP 257;机器闸 tools/audit_file_headers.py) +- 文件头 = `##` 文档注释,介绍本模块是什么;禁写变更叙事(改动史查 git log);禁文档反向链接(code-conventions §1.4.1) - 数值单一事实源——玩法数值只存 `data/tables/`(.tres)经 ConfigDB 单点读取;禁数值字面量与自建 `load()` 表路径 - RNG 单点——禁 `randomize()`/自建 RandomNumberGenerator,随机只经 `RngService` 统一流 - 架构事实唯一源——架构事实只认 `design/engineering/architecture/architecture.md`;禁立第二架构文档或决策文档体系,历史决策记录只进 git commit log diff --git a/design/engineering/code-conventions.md b/design/engineering/code-conventions.md index fdee417a..b489a111 100644 --- a/design/engineering/code-conventions.md +++ b/design/engineering/code-conventions.md @@ -21,17 +21,13 @@ ### 1.4 命名 = 领域命名,禁止系统 ID 前缀 文件名与类名禁止 `a1_`/`b1_`/`c1_` 等系统 ID 前缀(`a1_board_generator.gd` → `board_generator.gd`)。设计追溯不靠前缀:代码↔设计的追溯由 GDD 文档承担,系统 ID 只作为文档的追溯锚;文件头注不承担追溯职责,不写任何文档链接(§1.4.1)。豁免:D2 schema 类与 autoload;文档/夹具登记名(如 b4_golden)属文档层。 -### 1.4.1 文件头 = `##` 文档注释,介绍本模块,≤8 行,两类白名单制 +### 1.4.1 文件头 = `##` 文档注释,介绍本模块 -头注的存在性与内容范围以 Python 规范为权威(GDScript 语法近 Python,官方风格指南对文件头零条款,不自造标准):Google Python Style Guide §3.8.2 明文要求——"Files should start with a docstring describing the contents and usage of the module"(文件应以描述模块内容与用法的 docstring 开头);PEP 257——模块一般都应有 docstring,摘要压一行。 +头注以 Python 规范为权威(GDScript 语法近 Python,官方风格指南对文件头零条款,不自造标准):Google Python Style Guide §3.8.2——文件应以描述模块内容与用法的 docstring 开头;PEP 257——模块一般都应有 docstring,摘要压一行。载体只用 `##` 文档注释(Godot 官方载体,进编辑器 F1 帮助),头注以说清模块为度,长度不设硬限。 -载体与上限:只用 `##` 文档注释(Godot 官方载体,进编辑器 F1 帮助),总行数 ≤8(不含空行,从文件首个非空行到首个非注释代码行)。 +黑名单(出现即违规):日期与变更叙事——改动史查 `git log`/`git blame`,变更背景读迭代实现报告;与其他文档或其他文件头重复的内容——零新信息不写;一切文档反向链接——「实现 GDD:xxx」「指路:架构见 xxx」一类全部废止,代码↔设计追溯由 GDD 文档承担。 -白名单(只许两类):①职责摘要——这是什么,一句话;项目语境(垂直切片状态/验证目标)以括号并入本行。②使用约束——使用本文件前必须知道的禁令与边界,每条一行。 - -黑名单(出现即违规):日期与变更叙事——改动史查 `git log`/`git blame`,变更背景读迭代实现报告;与其他文档或其他文件头重复的内容——零新信息不写(pyguide §3.8.2.1);场景结构、生命周期等代码机制描述——"Never describe the code"(pyguide §3.8.5);一切文档反向链接——「实现 GDD:xxx」「指路:架构见 xxx」一类全部废止,代码↔设计追溯由 GDD 文档承担。 - -机器闸:`tools/audit_file_headers.py`(static_scan S10:行数上限+黑名单机械可判子集)。存量头注按白名单清偿(约 90 文件,清偿批进行中);清偿落地后闸增补「头注必须 `##` 开头」锁死载体;此间新增/改动的文件头必须即合规。 +机器闸:`tools/audit_file_headers.py`(static_scan S10:变更叙事黑名单机械可判子集)。行数上限与类别白名单已停用。 ### 1.5 禁止事实约定 任何"大家默认这么做"的惯例必须成文进本文件(或 AGENTS.md)才算存在。写代码时发现未成文但必须遵守的约定 → 当场补条文,不许靠惯性延续。 @@ -41,7 +37,7 @@ ## 2. 契约纪律——跨层/跨类调用的语义 ### 2.1 信号与事件契约成文 -每个跨类信号:参数语义、发送时点、消费方依赖,必须在发送方 `##` 文档注释成文,每信号一行;计入 §1.4.1 的 8 行上限,装不下时迁契约文档。状态机的每次迁移路径都必须发出对应事件——**缺一条路径的事件 = 消费方永久等待 = 软锁**。 +每个跨类信号:参数语义、发送时点、消费方依赖,必须在发送方 `##` 文档注释成文,每信号一行;装不下时迁契约文档。状态机的每次迁移路径都必须发出对应事件——**缺一条路径的事件 = 消费方永久等待 = 软锁**。 ### 2.2 跨层标识符语义单一且成文 位置(index)/ 句柄(handle)/ 键(key)是三种不同的东西。跨类传递标识符时,传递方的语义必须与接收方契约逐字一致,禁止凭"当前恰好相等"传值。 @@ -68,7 +64,7 @@ 4. **lambda 捕获循环变量按创建时值**——循环内先落地局部变量再捕获,或用 `bind`。 5. **重命名脚本必须同步 `.uid` 文件**;新增 `class_name` 后必须跑一次编辑器扫描刷新全局类缓存,否则 `--headless --script` 模式解析失败。 6. **`print` 格式占位符与实参类型必须匹配**(`%d` 配 String = 静默输出字面量)。 -7. **语言纪律已机器化为 S9 类型闸**(迭代 27——2026-10-17 用户裁写入)——`tools/audit_type_hints.py`,执行载体=静态扫描域 S9(`game/tests/static_scan.sh`),退出码 0=归零。扫描面=产品码(`game/core`+`game/data`+`game/presentation`;smoke/tests 豁免——测量面容器直构是既有惯例)。三规则:R1 无类型容器(显式非参数化 `Dictionary`/`Array` 注解)/R2 有值返回缺返回类型(纯副作用缺 `-> void` 属写法面不入闸)/R3 参数缺类型(`_init` 豁免——构造注入面形态自由)。 +7. **语言纪律已机器化为 S9 类型闸**——`tools/audit_type_hints.py`,执行载体=静态扫描域 S9(`game/tests/static_scan.sh`),退出码 0=归零。扫描面=产品码(`game/core`+`game/data`+`game/presentation`;smoke/tests 豁免——测量面容器直构是既有惯例)。三规则:R1 无类型容器(显式非参数化 `Dictionary`/`Array` 注解)/R2 有值返回缺返回类型(纯副作用缺 `-> void` 属写法面不入闸)/R3 参数缺类型(`_init` 豁免——构造注入面形态自由)。 8. **`:= {}` 推断形态不算债**——`var x := {}` 类赋值推断属类型推断合法面,不入 R1 扫描;只有显式写的非参数化容器注解才算无类型容器。 9. **行级白名单通道 `# type-hint: ignore`**——豁免该行不入 S9;豁免理由必须随行注明(现行例:`board_generator` 四函数的 db 参鸭子型——typed 参拒冒烟夹具 `_BoardRowStub` 注入)。 10. **`# rng-seed-exempt` 标记豁免通道**——S1/S2 随机函数扫描对该行豁免;限定用途=非玩法 RNG 消费面的引擎熵(现行例:组合根种子编辑框空态取 `randi()`——建种子不进玩法封闭流)。 @@ -96,5 +92,5 @@ ## 6. 流程纪律 1. **大改动三段走**:设计稿/伪代码 → 用户审阅 → 实现;实现禁止先于审阅。改动明细只进 git 提交信息,README 与代码内不写修改记录(doc-conventions 第 5 节「禁写变更记录」)。 -2. **实现批完成后的登记义务**:06 条目按 doc-conventions §12.1 推进状态,批次过程与结论进 git 提交信息与 `reports/`(2026-10-18 用户裁:根目录会话状态文件已废除,禁止再在其中登记条目)。 +2. **实现批完成后的登记义务**:06 条目按 doc-conventions §12.1 推进状态,批次过程与结论进 git 提交信息与 `reports/`(根目录会话状态文件已废除,禁止再在其中登记条目)。 3. **呈现层缺陷的教训回写 D1 GDD 设计输入**(信号载荷 schema / 场景级测试 / 时点状态可见性)。 diff --git a/design/engineering/doc-conventions.md b/design/engineering/doc-conventions.md index c6321303..3c39b101 100644 --- a/design/engineering/doc-conventions.md +++ b/design/engineering/doc-conventions.md @@ -11,7 +11,7 @@ **读者测试是每个小节的验收标准**:只读这一节,回答三个问题——这节管的是谁/什么?在什么情况下?会发生什么?答不出来,就重写这一节,而不是给看不懂的地方补注释。 -旧体系 lean 格式六条硬规则已停用(其解读对象 `design/archive/` 旧档已删除,现无适用文档;原表格占比 30% 口径随之作废)。`tools/gdd_lint.py` 现为现行文档机检三闸之一(gdd_lint / doc_link_audit / doc_term_audit,分级周期口径见 AGENTS.md);可读性仍是第一内容质量门,lint 是格式机检面,两者并行。 +`tools/gdd_lint.py` 现为现行文档机检三闸之一(gdd_lint / doc_link_audit / doc_term_audit,分级周期口径见 AGENTS.md);可读性是第一内容质量门,lint 是格式机检面,两者并行。 ## 2. 白话写作规则 @@ -56,6 +56,8 @@ **通行检验标准**:读者是业内人但没读过项目历史——需要作者解释才懂的词不合格,必须展开成完整白话句(换新名词不算改,展开才算改)。**写后自查**:凡自己都要停顿才能想起意思的词,一律展开。 +**词表冻结**:doc_term_audit 与术语表「用语规范」节的禁用词表不再扩充;扩表唯一入口=用户实读反馈并经用户裁决,由非迭代批写入,禁 agent 自行增词。 + ## 5. 结构纪律 | 规则 | 内容 | @@ -70,10 +72,10 @@ **数值纪律**:正文定规则、取值域、单位;平衡值进 `data/tables/`,provisional 必须标注;已锁数值事实源 = `game/data/tables/*.tres`(现行值)与 owner 文档正文(规则、取值域、单位)。 -**登记处唯一性(2026-10-19 用户裁)**:`design/registry/`(`entities.yaml`/`architecture.yaml`)已注销删除,禁再建第二处事实登记——术语进 术语表、数值进 `.tres`、架构进 架构文档、影响面靠全仓搜索概念规范名得出。强制收口条款: +**登记处唯一性**:`design/registry/`(`entities.yaml`/`architecture.yaml`)已注销删除,禁再建第二处事实登记——术语进 术语表、数值进 `.tres`、架构进 架构文档、影响面靠全仓搜索概念规范名得出。强制收口条款: 1. **双写失同步禁止**——任何数值变更必须同时同步引用该数值的 GDD 表格正文、`data/tables/` 行值与 schema 校验域、相关待办清单现状——三类之一未更新即视为变更未完成。 -2. **调参表锁数后删现行值列**——仅留 schema 模板与取值域,只留 schema 模板与取值域,指针指向 `.tres` 对应行键。 +2. **调参表锁数后删现行值列**——仅留 schema 模板与取值域,指针指向 `.tres` 对应行键。 3. **覆盖范围** = 奖励/状态/敌人/技能/充能/护甲等级/区间掷点/难度曲线/D_ref 等所有数值字段。 4. **维护通道** = 「设计批 → 同步批」两段式;数值表改完不等于修订完成。 5. **压缩/换装批** = 「`.tres` 落批 + 切片 smoke 跑通 + GDD 表格改为只留取值域与 `.tres` 指针 + 待办清单刷新」四步全收才记版本号。 @@ -101,7 +103,7 @@ ## 10. 会话状态——仓库根不设状态文件 -**2026-10-18 用户裁:根目录 `active.md` 连同「会话状态唯一状态源」这条规矩一起废除。** 判据来自对 869 个历史会话的读写统计:整文件被读 448 次、平均每次 14 KB 进上下文,但会话里关于它的思考九成花在「追加条目前先查尾部编号防撞号」与「并行会话同时改它导致的合并冲突与丢弃」上,明确写「从它所载内容得知某事实」的只有 20 个会话;文件 45 KB 里约 95% 是别处已有权威源的重复说法、已失真陈述或已完结批次的历史叙述。体量闸只能测条目数与死链,测不出语义失真:10-15 清到 8.6 KB/3 条,10-17 已回到 40 KB,用户为「只写不删」连续三次发火,规矩照样失效。 +**根目录 `active.md` 连同「会话状态唯一状态源」这条规矩一起废除。** 判据来自对 869 个历史会话的读写统计:整文件被读 448 次、平均每次 14 KB 进上下文,但会话里关于它的思考九成花在「追加条目前先查尾部编号防撞号」与「并行会话同时改它导致的合并冲突与丢弃」上,明确写「从它所载内容得知某事实」的只有 20 个会话;文件 45 KB 里约 95% 是别处已有权威源的重复说法、已失真陈述或已完结批次的历史叙述。体量闸只能测条目数与死链,测不出语义失真:10-15 清到 8.6 KB/3 条,10-17 已回到 40 KB,用户为「只写不删」连续三次发火,规矩照样失效。 废除后的分工:**现在做什么**看根目录 `roadmap.md` 顶部「当前位」节;**待办与待裁**看 [06-待办清单](../gdd/06-待办清单.md)(唯一登记处);**批次过程与结论**看 git 提交信息与 `reports/`;**跨会话教训**看记忆库。禁止在仓库根新建同类状态文件,也禁止在任何文档里另设「当前状态快照」节——两处记同一件事必然漂移,这正是本次统计查出七条失实陈述的成因。 @@ -120,7 +122,7 @@ | 出口清理项 | 每迭代出口检查单必含:本迭代中间产物逐份核对(结论已吸收、未决已迁移)后删除 | | 暂存地非档案库 | 中间文档有两处暂存地,入内文件默认到期即死:`reports/`(需求卡片+迭代产出物)、`design/research/`(调研/提案/评估/历史验收)。`design/` 各子目录不留验证截图——截图属一次性凭据,结论写进 06 或需求卡片后图像即弃(在途图放 `artwork/`,整目录不入 git);只有需要机器逐像素比对的基线图长期入库,落 `game/tests/golden/` | | 落档必写接收方 | 新报告落档时头部必须写明接收方——`06-待办清单.md` 第几条,或哪张需求卡片。写不出接收方的不落文件,内容在会话里交付即可 | -| 迭代实现报告 | 实现批收口的迭代级报告(各卡状态/代拍板追认单/GDD 反哺点清单),属中间文档,**落 `reports/` 不落 `design/`**(2026-10-17 用户裁:实现批禁写 `design/`,`reports/` 是其唯一可写目录):反哺点裁决落文吸收后按「证据只留最新」退役 | +| 迭代实现报告 | 实现批收口的迭代级报告(各卡状态/代拍板追认单/GDD 反哺点清单),属中间文档,**落 `reports/` 不落 `design/`**(实现批禁写 `design/`,`reports/` 是其唯一可写目录):反哺点裁决落文吸收后按「证据只留最新」退役 | | 证据只留最新 | 测试证据只保留最新一次迭代或最新一轮同类审计版本;新证据落位后同批删上一份;待人清单过人闸后同规退役 | **删除方式**:按 `design/engineering/concept-conventions.md` 第 2 节删除概念 SOP 口径——先查引用面(grep 文件名于阻塞域),改写或删除指路句,再删文件,收尾跑死链检查全绿。执行入口=项目技能 batch-closure(批后收尾与中间文档退役)。 @@ -142,37 +144,34 @@ 正文四属性模板: ``` -**现状**:现在缺什么、为什么是问题(关键处带 file:line 或文档指针)。工程直入条目必须在现状里指认证据(bug 证据或工程债条目)。 +**现状**=关联文档清单,一行一件:它是什么(设计定稿/需求卡片/相关文档)+文件路径+版本号与日期(闭合类文件必带);必要时在清单前配一句现状说明。机制解释与论证过程不写在这里,归权威文档。路径用普通文本或行内代码书写,机器可搜索。工程直入条目必须在现状里指认证据(bug 证据或工程债条目)。 **缺口**:还差哪一次设计讨论/哪份设计产物才能写卡。尚有未闭合的设计轨时此属性必须存在;全部设计轨闭合后删除。 **归属**:主责系统文档或线别。 **状态**:按状态机取词。 ``` -状态机按标题里的设计面分轨,状态一律取下例用词。状态行按**状态段累积制**书写:条目每推进一段,就把新状态段接在状态行末尾,段与段用+号连接,书写顺序=推进顺序;已过去的段一律保留、禁删——闭合凭据要留在行内,编排四查与开工核验拿它比对。每段各自按状态词白名单与凭据规则校验,+号只作状态段连接符。 +状态机按标题里的设计面分轨,状态一律取下例用词。状态行按**状态段累积制**书写:条目每推进一段,就把新状态段接在状态行末尾,段与段用+号连接,书写顺序=推进顺序;已过去的段一律保留、禁删——状态履历供编排四查与开工核验比对。每段各自按状态词白名单校验,+号只作状态段连接符。 ``` 各轨推进序列(双轨条目设计阶段两段并列推进,一文档轨一美术轨): -文档轨:待文档设计 → 文档设计中 → 文档设计已闭合(凭据=文档路径+版本号, - 例:文档设计已闭合(design/gdd/systems/xxx.md v1.2)) -美术轨:待美术设计 → 美术设计中 → 美术设计已闭合(凭据=样张过审、art-bible 条款版本, - 例:美术设计已闭合(样张过审、art-bible v3.x)) -双轨条目设计阶段示例:文档设计已闭合(design/gdd/systems/xxx.md v0.6)+美术设计中 -进入下游段(待写卡及之后)的前置条件——双轨:两个设计轨段都在场且都已闭合(带凭据);单轨:本轨闭合段(带凭据)在场 -下游共用序列:待写卡 → 已写卡(reports/ 下的需求卡片路径)→ 已编迭代 N → 完成即整条删除 -单轨累积示例(已编迭代):文档设计已闭合(design/gdd/systems/xxx.md v1.2)+已写卡(reports/需求卡片-xxx.md)+已编迭代 2 +文档轨:待文档设计 → 文档设计中 → 文档设计已闭合 +美术轨:待美术设计 → 美术设计中 → 美术设计已闭合 +进入下游段(待写卡及之后)的前置条件——双轨:两个设计轨闭合段都在场;单轨:本轨闭合段在场 +下游共用序列:待写卡 → 已写卡 → 已编迭代 N → 完成即整条删除 +单轨累积示例(已编迭代):文档设计已闭合+待美术设计+已写卡+已编迭代 2 ``` -凭据括号内禁用+号——+只作状态段连接符,凭据内需要并列多项时用顿号(如上例「样张过审、art-bible v3.x」),用+会被流水线闸误判为状态段。已编迭代 N 段的交叉核依据=同状态行内「已写卡」段括号里的卡片路径。 +状态行只写状态词:去掉特批标记与「(备选)」后缀后,残留任何括号即违规。闭合类状态词(文档设计已闭合/美术设计已闭合/已写卡/已写入)的证据——设计定稿路径+版本、art-bible 条款版本、需求卡片路径、落点文档+版本——一律写在现状的关联文档清单里,由流水线闸到正文核对;已编迭代 N 段的交叉核依据=现状清单里的需求卡片路径。 三条特殊通道: | 设计面 | 通道规则 | |---|---| | 工程直入 | 缺陷修复/工程债/测试基建/重构四类工程条目:登记即「待写卡」,凭现状里指认的证据跳过设计轨 | -| 反哺点专条 | 待裁决 → 已写入(落点=文档+版本)→ 删除 | +| 反哺点专条 | 待裁决 → 已写入 → 删除 | | 备选库条目 | 暂不排期、留在备选库的条目:状态词后缀「(备选)」 | -「已闭合」不带凭据不算合法状态词。特批标记见 12.4。 +特批标记见 12.4。 ### 12.2 roadmap 迭代行格式 diff --git a/design/engineering/process-conventions.md b/design/engineering/process-conventions.md index c8659157..dbd038f9 100644 --- a/design/engineering/process-conventions.md +++ b/design/engineering/process-conventions.md @@ -10,7 +10,7 @@ 主工作区(master 检出)只作合并落点,一切开发/设计改动禁止直接发生在主工作区: 1. **开工**:每批次先建独立 worktree:`git worktree add ../g-plan2-<任务名> -b <任务分支>`;所有改动与验证都在 worktree 内进行(未跟踪文件不会出现在新 worktree,需手工搬运) -2. **收尾**:迭代 loop 批次验证全绿(冒烟+场景探针)后在主工作区 `git merge --no-ff <任务分支>`,再 `git worktree remove`+删分支;合回前若 master 已被别的批次推进,先在分支里 `git merge master` 解冲突、重跑本域闸再合回。非 loop 批次默认完成不跑闸(两入口铁规),用户点名或当场问 +2. **收尾**:迭代 loop 批次验证全绿(冒烟+场景探针)后在主工作区 `git merge --no-ff <任务分支>`,再 `git worktree remove`+删分支;合回前若 master 已被别的批次推进,先在分支里 `git merge master` 解冲突、重跑本域闸再合回。非 loop 批次合回前同样按本批改动域跑闸(见 §3.10:纯文档批跑 `--docs`);游戏类测试(冒烟/单测/MC/探针)对它默认零执行(两入口铁规,见 §4),用户点名或当场问才跑 3. **豁免面**:仅 `.zcode/`(钩子与配置)与 `.qoder/`(本机 harness 配置)允许主工作区直改——两份实测均不入 git(走 worktree 反而带不进去,改动只对本机生效);其余一律走 worktree,主工作区 git commit 被钩子拦截 4. 本铁律由 PreToolUse 钩子 `.zcode/hooks/worktree-guard.sh` 强制兜底;钩子只约束 agent,用户手工改动不受限 @@ -21,14 +21,14 @@ | 段 | 入口技能 | 产出 | 出入口铁律 | |---|---|---|---| | 一·登记 | 无(闸管格式) | 06-待办清单条目 | 条目=标题登记元数据+正文四属性(现状/缺口/归属/状态);标题登记后不再变,正文随进程演进。格式与状态机权威=doc-conventions 第 12 节 | -| 二·文档设计/美术设计 | doc-design(文档轨,兼任反哺点写入)/asset-ingest(美术录入;样张素材由用户主导产出) | GDD 文档或 art-bible/过审样张素材 | 用户提起或从 06 取出;会话内进行、用户主导、禁无监管自跑;经用户点头确认心智一致才许写入文档;完成判据=待裁点清零,带未裁点的是讨论稿;轨闭合凭据记入 06 状态(文档轨=文档路径+版本号,美术轨=样张过审+art-bible 条款版本) | -| 三·写需求卡片 | req-card | 需求卡片 | 轨闭合后用户发令;新玩法/新系统/新内容必须有设计定稿前置,例外=工程直入四类(缺陷修复/工程债/测试基建/重构)凭证据跳过设计轨;卡片必经 grilling 多轮复核、零待裁点才成立;写完在 06 状态记「已写卡」+卡片路径(防遗忘) | +| 二·文档设计/美术设计 | doc-design(文档轨,兼任反哺点写入)/asset-ingest(美术录入;样张素材由用户主导产出) | GDD 文档或 art-bible/过审样张素材 | 用户提起或从 06 取出;会话内进行、用户主导、禁无监管自跑;经用户点头确认心智一致才许写入文档;完成判据=待裁点清零,带未裁点的是讨论稿;轨闭合凭据记入 06 现状清单(文档轨=文档路径+版本号,美术轨=art-bible 条款版本) | +| 三·写需求卡片 | req-card | 需求卡片 | 轨闭合后用户发令;新玩法/新系统/新内容必须有设计定稿前置,例外=工程直入四类(缺陷修复/工程债/测试基建/重构)凭证据跳过设计轨;卡片必经 grilling 多轮复核、零待裁点才成立;写完在 06 状态记「已写卡」,卡片路径记入现状清单(防遗忘) | | 四·迭代编排 | iter-plan | roadmap 迭代行 | 编排四查:①每卡卡片文件存在 ②每卡设计闭合凭据齐(或工程直入证据)③总估时 ≤2 周 ④写完 roadmap 行后跑流水线闸确认绿;编入未完成迭代,新开迭代行经用户确认 | | 五·实现 | iter | 代码与配置,可运行的游戏 | 需求卡片永不单独施工,统一由用户指定迭代号触发(=U0 开工令),按 iter 技能与本文 §3 执行;**本段是代码实现批:禁写 `design/` 与根规则文件,产出物只落 `reports/`(见 §3 第 13 条)**;设计权威文档(GDD/art-bible)批内一律不更新;完成人闸=实机目检清单+代拍板追认单登记交用户即完成批内义务 | **实现段零裁断**:实现段的输入在编排段出口已锁死(卡片零待裁点+设计闭合凭据齐+编排四查过)。实现中冒出卡片没写清的分歧=上游缺陷——停该卡、06 状态回退+缺口补记,退回上游;禁自答、禁内联提问求裁断;该卡停摆不阻塞同迭代其他卡。环境故障与测试红走异常分级(自救重试/记录继续/停机呈报)。代拍板白名单保留:授权发生在卡片审问阶段,实现只执行预授权;批后追认单=备案确认。 -**流水线闸**:`tools/pipeline_gate.py` 机检 06-待办清单与 roadmap 两文件的格式与互相引用;将注册进 `run_all_gates.sh` 文档域(注册归第二批,本批不注册)。流程文档的条目格式、迭代行格式与状态机细则见 doc-conventions 第 12 节。 +**流水线闸**:`tools/pipeline_gate.py` 机检 06-待办清单与 roadmap 两文件的格式与互相引用;已注册进 `run_all_gates.sh` 文档域。流程文档的条目格式、迭代行格式与状态机细则见 doc-conventions 第 12 节。 ## 3. 批次工作流标准清单 @@ -50,10 +50,10 @@ 9. **验收函数变异验证**——新增/改写的验收函数(冒烟断言/探针自检/闸机判据)必须配一次变异验证:故意把被测件改坏成该类缺陷形态 → 跑最窄那道闸确认变红 → `git checkout` 精确还原;变异点/跑的闸/红输出摘要/还原结论四件记入实现报告变异验证记录表;**无变异红记录的断言不写「已验收」,只写「已实现,拦截能力未证」**(细则见 test-conventions §6) **完成** -10. **批末按域验收才合并**——在任务 worktree 内跑 `tools/run_all_gates.sh`,**按本批改动域选档**:本批改动触及 `game/`(游戏工程代码、测试、探针、场景)→ `--code`;不触及 `game/` 的一切改动(`design/`、根规则文件、`tools/` 工具脚本、`.zcode/` 配置等)→ `--docs`;同批混触 `game/` 与文档面 → 全量档不带参数。所选域全绿才合回 master。该脚本是全部验证闸的**唯一入口、唯一清单与唯一域划分**,闸件增减、分域调整都只改它;**本文与其他文档禁另列闸件清单**(清单散落多处正是 iter27 漏跑 `probe_gate --full` 的成因)。跑完写回执 `game/tests/.gates/receipt.json`(含 `domain` 字段),合回时由 worktree-guard 按 diff 路径推域强制校验。闸件(`tools/` 下机检脚本与闸壳)自身的改动不占合回全量——其质量义务=落批时的变异验证(test-conventions §6),闸真崩溃时合回闸 fail-closed(跑不出回执即拦),不以合回全量为兜底 +10. **批末按域验收才合并**——在任务 worktree 内跑 `tools/run_all_gates.sh`,**按本批改动域选档**:本批改动触及 `game/`(游戏工程代码、测试、探针、场景)→ `--code`;不触及 `game/` 的一切改动(`design/`、根规则文件、`tools/` 工具脚本、`.zcode/` 配置等)→ `--docs`;同批混触 `game/` 与文档面 → 全量档不带参数。所选域全绿才合回 master。该脚本是全部验证闸的**唯一入口、唯一清单与唯一域划分**,闸件增减、分域调整都只改它;**本文与其他文档禁另列闸件清单**(清单散落多处正是 iter27 漏跑 `probe_gate --full` 的成因)。跑完写回执 `game/tests/.gates/receipt.json`(含 `domain` 字段),合回时由 worktree-guard 按 diff 路径推域强制校验(五况拦截:缺回执/quick 模式/回执 commit ≠ HEAD/域不覆盖本次改动/含新增红)。闸件(`tools/` 下机检脚本与闸壳)自身的改动不占合回全量——其质量义务=落批时的变异验证(test-conventions §6),闸真崩溃时合回闸 fail-closed(跑不出回执即拦),不以合回全量为兜底 11. **合并后主区按域复跑**——合并可能引入冲突或环境差异,落回 master 后按本批改动域复跑:触及 `game/` 的批=全量复跑(维持);纯文档域批=复跑文档域档(秒级),不再全量 -12. **批次完成后的登记义务**——合回 master 后按 doc-conventions §12.1 推进 06 条目状态(做完整条删除),涉及迭代编排的在 roadmap 迭代总表与顶部「当前位」节换代——执行入口=项目技能 batch-closure(批后收尾与中间文档退役),跨会话教训写记忆库。批次过程与结论由 git 提交信息承载,禁止再写会话状态文件(2026-10-18 用户裁,见 doc-conventions 第 10 节)。`design/` 与根规则文件(`AGENTS.md`/`roadmap.md`)实现批禁写,见 §13 -13. **文档同步闸(2026-10-17 改口径:实现批禁写文档)**——实现批**禁写 `design/` 整个目录与根规则文件**,要往外交代的东西一律落 `reports/`:实现报告 `reports/iter-实现报告-<日期>.md`(各卡状态+实机目检总清单+遗留读数义务)、代拍板追认单 `reports/iter-代拍板-<日期>.md`、GDD 反哺点清单 `reports/iter-反哺点-<日期>.md`(每条写清哪个文件哪一节、改成什么、依据是什么)。设计权威文档(GDD/art-bible)**任何批都不直改**:用户在会话中逐点裁决后,由非迭代批(工具/规则/文档批)写入 `design/`(执行入口=doc-design 技能),并把反哺条目从 `reports/` 清掉(吸收即死;退役执行=batch-closure 技能)。机械面文档(roadmap 行/术语表/README 工具注)同样归非迭代批在合并前更新。反哺点未落地期间相关 GDD 节视为待反哺,读前先查 `reports/` 与 06;需求卡片必列「关联文档同步面」按两层标注 +12. **批次完成后的登记义务**——合回 master 后按 doc-conventions §12.1 推进 06 条目状态(做完整条删除),涉及迭代编排的在 roadmap 迭代总表与顶部「当前位」节换代——执行入口=项目技能 batch-closure(批后收尾与中间文档退役),跨会话教训写记忆库。批次过程与结论由 git 提交信息承载,禁止再写会话状态文件(见 doc-conventions 第 10 节)。`design/` 与根规则文件(`AGENTS.md`/`roadmap.md`)实现批禁写,见 §13 +13. **文档同步闸(实现批禁写文档)**——实现批**禁写 `design/` 整个目录与根规则文件**,要往外交代的东西一律落 `reports/`:实现报告 `reports/iter-实现报告-<日期>.md`(各卡状态+实机目检总清单+遗留读数义务)、代拍板追认单 `reports/iter-代拍板-<日期>.md`、GDD 反哺点清单 `reports/iter-反哺点-<日期>.md`(每条写清哪个文件哪一节、改成什么、依据是什么)。设计权威文档(GDD/art-bible)**任何批都不直改**:用户在会话中逐点裁决后,由非迭代批(工具/规则/文档批)写入 `design/`(执行入口=doc-design 技能),并把反哺条目从 `reports/` 清掉(吸收即死;退役执行=batch-closure 技能)。机械面文档(roadmap 行/术语表/README 工具注)同样归非迭代批在合并前更新。反哺点未落地期间相关 GDD 节视为待反哺,读前先查 `reports/` 与 06;需求卡片必列「关联文档同步面」按两层标注 14. **实机目检归用户,只登记不阻塞**——真人检测项登记进实现报告目检总清单与 07-体验验证清单即完成批内义务;禁把等目检当停工理由或完成前置 15. **中间产物吸收即死**——细则见 AGENTS.md 硬性红线与 doc-conventions 第 11 节 diff --git a/design/engineering/test-conventions.md b/design/engineering/test-conventions.md index f8bc7849..244143e3 100644 --- a/design/engineering/test-conventions.md +++ b/design/engineering/test-conventions.md @@ -66,7 +66,7 @@ **判据强弱分层**:同一缺陷面往往需要多件配合——**可见性/状态源类**缺陷由 `is_visible_in_tree`、树序、状态源取值的**运行期断言**抓;**内容/观感类**缺陷由 **golden 逐像素比对**抓;**占比/统计类**判据(墨色占比、纹理幅度)只能兜「整框空白/整框糊/压 busy 纹理」,是补充不是主力。写卡时按此分层配齐,别指望一条断言包打。 -## 7. 判定三硬闸——闸承载的构造义务(迭代 29 三硬闸 2026-10-17 用户裁升格为纪律) +## 7. 判定三硬闸——闸承载的构造义务(迭代 29 起) 任何**新增或改写的闸承载**(闸脚本/批跑编排/探针入口)必须三闸齐备;现行各闸状态登记归架构文档「测试与质量域」节(本文不另列闸件清单): @@ -76,9 +76,9 @@ - 负面套件(测试目标就是产生错误输出)仅可豁免第 2 闸,且须在 manifest 显式标记,其余两闸照判。 - 子进程输出须经系统命令解释器重定向落盘再读——`OS.execute` 的输出管道在本机恒空。 -**新写测试件全类型标注**(2026-10-17 用户裁写法纪律)——新写的测试件(冒烟断言/探针/单测)参数、返回值、容器一律带类型标注,与 S9 对产品码的要求同型;存量不强制清扫,被批次触碰时顺带换代。暂不机器闸(S9 扫描面=产品码,smoke/tests 豁免是测量面直构惯例的既有裁量)。 +**新写测试件全类型标注**——新写的测试件(冒烟断言/探针/单测)参数、返回值、容器一律带类型标注,与 S9 对产品码的要求同型;存量不强制清扫,被批次触碰时顺带换代。暂不机器闸(S9 扫描面=产品码,smoke/tests 豁免是测量面直构惯例的既有裁量)。 -## 8. 判定可靠性优先于覆盖率(迭代 29 核心命题 2026-10-17 用户裁成节) +## 8. 判定可靠性优先于覆盖率(迭代 29 核心命题) - 「跑一遍没崩=通过」无效:测试绿只证明**当前代码没犯这个错**,不证明**犯了这个错会被抓住**;断言存在不等于断言执行。 - **脚本错误会静默中断所在函数的剩余断言,而套件仍报全绿**(机制事实):GDScript 无脚本错误陷阱 API,错误不改进程退出码、不计失败数。三处实证:①2026-09-19「309 项 0 失败」实为断言未跑全(状态记录 83);②敌人表行集纪律 10 条断言因定型数组赋值错误从未执行(迭代 29 修复后两条正向见红=夹具本缺锚行);③`Callable` 形参类型写错致解析函数返回 null、后续断言整段蒸发。 diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index 3e17ea2d..ebd8a5f6 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -207,11 +207,11 @@ #### 冒险前资源配比预设(构筑提案)(2026-09-18 登记,来源=会话提及,设计面=文档轨) -**现状**:2026-09-18 用户提案,方向评估通过,登记在案。核心想法=玩家在**开始冒险前**预设地图战斗资源的类型配比——预设的是**分布**(九型格面池的正向权重占比;2026-10-04 立项裁决批口径 gp 型入池成九型,正向权重合计 77),不是落位:装板摇号仍按专属随机流摇出各格类型身份,玩家定分布、摇号定落位(与既定随机性立场相容)。两分法:① **基础资源配比**——正向行权重经覆盖值通道在开局注入;② **关卡特殊资源**——不同关卡(board_biome 图主题)携带配比池之外的特殊资源与差异化分布。设计红利=危险格与安全格同池+极性矩阵使配比自带代价轴(调高某型权重,安全格正向与危险格负向同步变多),不是免费午餐;注入通道=[元进度](systems/跨局循环/元进度.md) v1.0 已定稿的「冒险开始参数面与覆盖值通道」,零新机制;②正是[棋盘生成](systems/排雷循环/棋盘生成.md) board_biome 上下文与[地图战斗资源](systems/战斗循环/地图战斗资源.md)差异化插槽的启用场景。**八项裁决已全裁(2026-10-04 用户令「拍板点全部使用推荐」)**:①预算=组合制(总量挪点为骨架〔总和恒 77〕+每型上下限包络+容量随营地解锁渐进〔gp 首发不可调/预设档 3 套/下限 >0〕);②主权=设计者定包络与默认、玩家包络内分配(验收=默认分布锚+极端构筑护栏带);③容量柜台=奖励格图鉴承接;④注入语义=差值向量(存相对默认偏移 ΣΔ=0,集合操作保留在解锁层作辅语义);⑤渠道边界=清图槽差异化先行+三句不混池口径;盘问轮四裁随落(合成序=表值→玩家配比差值→包络钳制→图级变异偏斜→同调硬币偏置;图鉴柜台逐型商品;冒险开始锁档;包络宽度随容量分级放宽)。全案与淘汰依据原载提案 §八/§九/§十(该提案文件已随吸收即死退役,git 历史可考;需求卡片冻结在档)。影响面/依赖/被依赖清单原载本条(排雷/战斗/冒险/表现四循环十余文档指针),重启时自 git 历史取全文本。**挂起(2026-10-05 用户令)**:移出 roadmap 迭代 14(⑥号卡撤销)——暂不做,本条保留为挂起待办;八项裁决与需求卡片全部冻结保留(需求卡片文件头已挂冻结横幅);重启须用户另行发令。**凭据版本复核(2026-10-18,文档体检第 10 项)**:本条两处写的 `元进度.md v1.0` 是定稿当时的版本号,该文档现行已 v1.21;经查「冒险开始参数面」与「覆盖值通道」在 v1.21 里原样在役(该文档 :26/:98/:100/:119 四处),v1.16 与 v1.18 两行只对注入节作追加说明、未推翻通道结论——闭合判据仍成立,凭据按历史记载保留不改号。 +**现状**:构筑提案 2026-09-18 立项、八项裁决全裁(2026-10-04),设计闭合机制=[元进度](systems/跨局循环/元进度.md)「冒险开始参数面与覆盖值通道」(零新机制);2026-10-05 挂起——移出 roadmap 迭代 14,八项裁决与需求卡片冻结保留,重启须用户另行发令;全案与淘汰依据原载已退役提案(git 历史可考),裁决细节冻结在卡片。关联文档:[元进度](systems/跨局循环/元进度.md) v1.0(闭合凭据;现行 v1.21 已复核在役,2026-10-18 文档体检第 10 项);需求卡片 reports/需求卡片-冒险前资源配比预设批-2026-10-04.md(文件头挂冻结横幅)。 **归属**:[地图战斗资源](systems/战斗循环/地图战斗资源.md)修订批(基础配比的权重覆盖语义 + GDD 修订)与[元进度](systems/跨局循环/元进度.md)(解锁容量与注入生产者)共裁;呈现面归[HUD 框架](systems/表现与支撑/HUD框架.md)与[教学引导](systems/表现与支撑/教学引导.md)顺带。 -**状态**:文档设计已闭合(八裁全落零拍板点,机制依赖面=元进度.md v1.0「冒险开始参数面与覆盖值通道」)+已写卡(reports/需求卡片-冒险前资源配比预设批-2026-10-04.md)(备选) +**状态**:文档设计已闭合+已写卡(备选) #### GP 经济换算失衡——GP 袋面值与商店价格的换算关系复查(2026-10-07 登记,来源=审计发现,设计面=文档轨) @@ -547,61 +547,67 @@ #### 营地交互重做·五张需求卡片(2026-10-18 登记,来源=会话提及,设计面=文档轨) -**现状**:2026-10-17~18 需求讨论澄清会话产出结论文档 `design/research/需求澄清-营地交互重做-2026-10-18.md` v1.0(目标体验原话/目标结构树+纵深稿/10 条交互裁决/验收口径/切批原则/遗留待裁),用户令按工作内容维度拆卡、卡片不预占迭代号。五卡已写(顺序=执行顺序,估时附后):①存档制数据层改造批(隐式单档→3 存档位,≈4.5–5.5d)②主菜单三入口化批(6 钮→3 钮,≈2.5–4d)③选档界面新建批(≈4.5–5.5d)④营地场景图新建批(最大件,≈9–12d)⑤Esc 浮窗与营地顶栏批(≈3–4.5d)。三道复核:grilling 子 Agent 对抗审查(五卡各一)→v1.1;用户裁定「事项按推荐的来」→v1.2;用户两次订正(**卡④留在批内不踢出**;前置由谁解决/何时解决由用户定,美术/设计线=用户自立批〔铁律 2〕,Agent 不代跑不代产——曾越权起草的点选反馈设计稿 v0.1 已撤回删除)→卡④ v2.2。①②③⑤ 零待裁点可编工程波次:②③ 硬耦合同波(「进入存档」钮落点=选档界面),① 是 ③ 前置;⑤ 随 ④ 代码波同行。 +**现状**:2026-10-17~18 需求讨论澄清会话产出结论文档,用户令按工作内容维度拆卡、卡片不预占迭代号。五卡已写(顺序=执行顺序):①存档制数据层改造批 ②主菜单三入口化批 ③选档界面新建批 ④营地场景图新建批 ⑤Esc 浮窗与营地顶栏批(各卡估时与内容见卡片自身)。三道复核:grilling 子 Agent 对抗审查(五卡各一)→v1.1;用户裁定「事项按推荐的来」→v1.2;用户两次订正(**卡④留在批内不踢出**;前置归用户自立批,Agent 不代跑不代产——曾越权起草的点选反馈设计稿 v0.1 已撤回删除)→卡④ v2.2。①②③⑤ 零待裁点可编工程波次:②③ 硬耦合同波(「进入存档」钮落点=选档界面),① 是 ③ 前置;⑤ 随 ④ 代码波同行。关联文档: +- 设计澄清定稿:design/research/需求澄清-营地交互重做-2026-10-18.md(v1.0:目标体验原话/目标结构树+纵深稿/10 条交互裁决/验收口径/切批原则/遗留待裁) +- 卡①:reports/需求卡片-存档制数据层改造批-2026-10-18.md +- 卡②:reports/需求卡片-主菜单三入口化批-2026-10-18.md +- 卡③:reports/需求卡片-选档界面新建批-2026-10-18.md +- 卡④:reports/需求卡片-营地场景图新建批-2026-10-18.md(v2.2,美术轨未闭合,见缺口) +- 卡⑤:reports/需求卡片-ESC浮窗与营地顶栏批-2026-10-18.md **缺口**:卡④(营地场景图)美术轨未闭合,五项前置批内登记待销号——P1 美术渠道 A/B(**待用户裁**,推荐 A);P2 像素规格(Q6 甲过渡口径已裁,执行归用户线);P3 点选反馈设计稿(用户线,未受命开工;Agent 曾越权起草 v0.1,已按用户令撤回删除);P4 参照物(用户后续找);P5 GDD/art-bible 落文(定稿后用户发令)。销号完毕且美术定稿(样张过审+art-bible 条款版本)后卡④方可进代码实现波次。 -**归属**:营地交互重做(数据层+呈现层+美术线;五卡路径见状态行,批次归属与波次由用户按工作量另裁) +**归属**:营地交互重做(数据层+呈现层+美术线;五卡路径见现状清单,批次归属与波次由用户按工作量另裁) -**状态**:文档设计已闭合(design/research/需求澄清-营地交互重做-2026-10-18.md v1.0)+待美术设计+已写卡(reports/需求卡片-存档制数据层改造批-2026-10-18.md)+已写卡(reports/需求卡片-主菜单三入口化批-2026-10-18.md)+已写卡(reports/需求卡片-选档界面新建批-2026-10-18.md)+已写卡(reports/需求卡片-营地场景图新建批-2026-10-18.md)+已写卡(reports/需求卡片-ESC浮窗与营地顶栏批-2026-10-18.md) +**状态**:文档设计已闭合+待美术设计+已写卡+已写卡+已写卡+已写卡+已写卡 #### 需求卡片入库纪律未登记——502 批遗留的悬空待办(2026-10-18 登记,来源=批次移交,设计面=反哺点) -**现状**:2026-10-16 迭代 29 编入批(提交 `21c83f5`)认定「需求卡片写进了 roadmap 却没在 06 登记」属流程漏洞,需要补一条卡片入库纪律。该条至今在 06 清单内查无(2026-10-17 与 2026-10-18 两次全文检索零命中)。唯一记过它的地方是根目录状态文件未决面第 31 行,该文件已于 2026-10-18 用户裁废除,故改记本条防遗忘。 +**现状**:2026-10-16 迭代 29 编入批(提交 `21c83f5`)认定「需求卡片写进了 roadmap 却没在 06 登记」属流程漏洞,需要补一条卡片入库纪律。该条至今在 06 清单内查无(2026-10-17 与 2026-10-18 两次全文检索零命中)。唯一记过它的地方是根目录状态文件未决面第 31 行,该文件已于 2026-10-18 用户裁废除,故改记本条防遗忘。待裁:这条纪律要不要立;立则写进归属所指的 process-conventions。 **归属**:design/engineering/process-conventions.md 五段流水线的登记段 -**状态**:待裁决(这条纪律要不要立;立则写进 process-conventions) +**状态**:待裁决 --- #### req-card 技能的 WorkBuddy 与 ZCode 两份副本内容不一致——取齐待裁(2026-10-18 登记,来源=批次移交,设计面=反哺点) -**现状**:用户级技能 req-card 在本机有两份副本,分别位于 WorkBuddy 与 ZCode 两个 harness 的用户目录 skills/req-card/SKILL.md(都在仓库之外,仓内没有任何登记处)。2026-10-18 逐字节比对:两份内容不同——迭代 28 那批只补了 ZCode 一份,WorkBuddy 那份没跟着改。这条欠账此前只记在根目录会话状态文件的未决面第 32 行,该文件已于 2026-10-18 用户裁废除,故改记本条。 +**现状**:用户级技能 req-card 在本机有两份副本,分别位于 WorkBuddy 与 ZCode 两个 harness 的用户目录 skills/req-card/SKILL.md(都在仓库之外,仓内没有任何登记处)。2026-10-18 逐字节比对:两份内容不同——迭代 28 那批只补了 ZCode 一份,WorkBuddy 那份没跟着改。这条欠账此前只记在根目录会话状态文件的未决面第 32 行,该文件已于 2026-10-18 用户裁废除,故改记本条。待裁:以哪一份为权威取齐,或两份各自演化。 **归属**:用户级技能 req-card(仓库外两份副本) -**状态**:待裁决(以哪一份为权威取齐,或两份各自演化) +**状态**:待裁决 --- #### 「魔法道具」与「罕见」两个旧叫法的残留未扫——扫不扫待裁(2026-10-18 登记,来源=批次移交,设计面=反哺点) -**现状**:「魔法道具」随 2026-09-15 可选类道具删除而失效,「罕见」随 2026-09-14 分辨率档位批换装而失效,正文里仍有残留。2026-10-18 实数(全仓 markdown 检索):魔法道具 23 处、罕见 17 处;此前根目录状态文件记的「约 30 处/约 18 处」系旧读数。两词都不在 `tools/doc_term_audit.py` 的退役词表里,机器闸抓不到,只能人工裁。 +**现状**:「魔法道具」随 2026-09-15 可选类道具删除而失效,「罕见」随 2026-09-14 分辨率档位批换装而失效,正文里仍有残留。2026-10-18 实数(全仓 markdown 检索):魔法道具 23 处、罕见 17 处;此前根目录状态文件记的「约 30 处/约 18 处」系旧读数。两词都不在 `tools/doc_term_audit.py` 的退役词表里,机器闸抓不到,只能人工裁。待裁:扫或不扫;扫则把两词追加进 doc_term_audit 退役词表防再犯。 **归属**:design/gdd/ 正文用语(权威对照=design/gdd/术语表.md) -**状态**:待裁决(扫或不扫;扫则把两词追加进 doc_term_audit 退役词表防再犯) +**状态**:待裁决 --- #### 「通关」与「通过第 N 关」两种口径混用——统一与否待裁(2026-10-18 登记,来源=批次移交,设计面=反哺点) -**现状**:「通关」一词既被用来指「打完一整局冒险」,也被用来指「通过第 N 关」,2026-10-18 实测 design/gdd 内 188 处(此前状态文件记 273 处,口径是全仓)。歧义直接影响难度曲线读数与验收判据的表述——同一个「通关率」两种读法差一个数量级。 +**现状**:「通关」一词既被用来指「打完一整局冒险」,也被用来指「通过第 N 关」,2026-10-18 实测 design/gdd 内 188 处(此前状态文件记 273 处,口径是全仓)。歧义直接影响难度曲线读数与验收判据的表述——同一个「通关率」两种读法差一个数量级。待裁:是否定单一口径并逐处改写。 **归属**:design/gdd/01-核心循环.md 与难度曲线、验收类文档的措辞口径 -**状态**:待裁决(是否定单一口径并逐处改写) +**状态**:待裁决 --- #### 流程动词族黑话的第二波清扫待发令——GDD 正文约三千处(2026-10-18 登记,来源=批次移交,设计面=反哺点) -**现状**:2026-10-15 用语规范批只按 A 表替换了词面约 250 处(十二行),流程动词族——需要作者额外解释才看得懂的一类说法——在 GDD 正文仍有约三千处未处理。第二波至今未发令。 +**现状**:2026-10-15 用语规范批只按 A 表替换了词面约 250 处(十二行),流程动词族——需要作者额外解释才看得懂的一类说法——在 GDD 正文仍有约三千处未处理。第二波至今未发令。待裁:第二波的范围与发令时点。 **归属**:design/gdd 全树正文用语(权威词表=design/gdd/术语表.md 用语规范节) -**状态**:待裁决(第二波的范围与发令时点) +**状态**:待裁决 --- @@ -629,13 +635,15 @@ #### 计数器寿命域未统一(2026-10-18 登记,来源=会话提及,设计面=文档轨) -**现状**:2026-10-19 用户裁定推翻「寿命域统一口径」方向(原方案五档/四档枚举、`domain` 键扩词表整体作废——作废因由=该方案隐含前提「引擎持有状态、需要字段说明它活多久」被推翻,见提案 §8),改走**效果引擎无状态化重构**:引擎零运行时状态,计数器按 round/battle/level/adventure 四桶外置、由各生命周期宿主对象持有(寿命由宿主生灭决定,不再需要寿命字段),归属用 counter_id 前缀表达(`round_`/`lvl_`/`adv_`/无前缀=battle,`meta_` 非法)+加载期强校验。设计定值与实现设计缺口已全部闭合(提案=design/research/提案-效果引擎无状态化-2026-10-19.md,§7 定值+§7.10 闭合)。本条目原指认的三套机制并存问题由该重构一并消解:①`domain`/`reset_at` 两字段随重构删除;②「按关重置」硬编码名单(`adventure_runner.gd:838-841`)随 level 桶宿主化消失;③`run_ledger.gd:42` 空容器早退自锁缺陷随搬运链删除自动消解(代价=行为变更:adventure 域计数器变真跨战持久、天赋树锋/守变真每关限 2 次——削弱方向已定性,提案 §7.7/§7.8)。副产定值:`pain_layers` 名实不符归 battle、`dig_combo` 死读数随重构顺带删除(提案 §7.10.14)。 +**现状**:原「寿命域统一口径」方案 2026-10-19 作废,改走效果引擎无状态化重构(提案 §8)。关联文档: +- 设计定稿:design/research/提案-效果引擎无状态化-2026-10-19.md(v1.2,2026-10-20 §7.10 闭合) +- 需求卡片:reports/需求卡片-效果引擎无状态化批-2026-10-20.md **证据面缺口(迭代 31 卡② 移交)**:`domain=battle` 每战清零与 `domain=adventure` 跨战持久这一对判据,现无法由单元测试 rig 变异证红(`feat_vouchers_test` 的变异②只钉住事件发射时机,未覆盖寿命域)。闭合此项时须在 runner/MC 面补一次「adventure 域计数器跨战持久 vs battle 域清零」的对照读数,或在文档批确认该判据只由代码注释与装载面约束、不设机检。 **归属**:architecture.md 与 game/core/effect_engine.gd(待立独立批) -**状态**:待裁决(是否统一寿命域口径——2026-10-19 已裁:统一口径方案作废,改走无状态化重构)+文档设计已闭合(design/research/提案-效果引擎无状态化-2026-10-19.md v1.2——2026-10-20 §7.10 闭合)+待写卡+已写卡(reports/需求卡片-效果引擎无状态化批-2026-10-20.md)+已编迭代 32 +**状态**:待裁决+文档设计已闭合+待写卡+已写卡+已编迭代 32 --- @@ -645,7 +653,7 @@ **归属**:增益状态.md(:10/:14/:44 及连带指路句);art/ 两文件(等 `gpsweep-20261019` 合回) -**状态**:待裁决(第①项增益状态用词改名与否)+待裁决(第②项 GP 更名分支合回时机) +**状态**:待裁决+待裁决 --- @@ -669,7 +677,7 @@ **归属**:①`奇物.md` §1.1/§2.2/v2.2 行(已订正写入文档);②`奇物.md` §1.3(:121/:223/:229)与 `02-系统清单.md:49`(待裁) -**状态**:已写入(design/gdd/systems/冒险循环/奇物.md v3.19——第①项专长凭证归类订正)+待裁决(第②项资源判据句,心智模型未对齐,不列候选不提前处置) +**状态**:已写入+待裁决 --- @@ -685,9 +693,11 @@ **不做(待用户另裁)**:术语表 A 表词一族、doc-conventions 第 4 节流程动词一族、简明技术中文(STC)通用禁用词一族——三族的逐词计数与清单见卡片 §4「不做」表(本行不复制词面:06 正文引述禁词会自指引爆 doc_term 补充通道,判红)。 +需求卡片:reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md(v1.3)。 + **归属**:game/ 代码与数据表(代码域,走独立 worktree 批;`AGENTS.md` 与 `design/` 依流水线红线本批禁碰,S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`) -**状态**:已写卡(reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md,**v1.3**)+已编迭代 32 +**状态**:已写卡+已编迭代 32 --- diff --git a/design/gdd/术语表.md b/design/gdd/术语表.md index 5c080b48..f2cdb7bb 100644 --- a/design/gdd/术语表.md +++ b/design/gdd/术语表.md @@ -99,7 +99,7 @@ 词面纪律的登记处。通用禁用词与选词以**简明技术中文(STC)词表**为权威:外部技能文件 `C:\Users\DK\.zcode\skills\simplified-technical-chinese\词表.md`,约 170 条,配检查脚本 check.py。 -本仓库的机器闸 = `tools/doc_term_audit.py`,已吸收本节项目裁项。本节只登记两类裁项:A 已裁替换、B 豁免条款。历史退役词(雷格/正主/落籍等 7 组)见下方「退役词对照」节,不与 A 表重复。 +本仓库的机器闸 = `tools/doc_term_audit.py`,已吸收本节项目裁项。**词表冻结**:本节与该闸的禁用词表不再扩充,扩表唯一入口=用户实读反馈并经用户裁决(由非迭代批写入,agent 禁自行增词)。本节只登记两类裁项:A 已裁替换、B 豁免条款。历史退役词(雷格/正主/落籍等 7 组)见下方「退役词对照」节,不与 A 表重复。 ### A. 已裁替换(写新文本必须用「用」列) diff --git a/game/tests/static_scan.sh b/game/tests/static_scan.sh index 245ffa6e..60441862 100644 --- a/game/tests/static_scan.sh +++ b/game/tests/static_scan.sh @@ -43,11 +43,11 @@ else fail=1 fi -# S10 — 文件头闸(code-conventions §1.4.1:头注 ≤8 行+日期/变更叙事黑名单) +# S10 — 文件头闸(code-conventions §1.4.1:## 载体+日期/变更叙事黑名单;行数上限已停用) if python tools/audit_file_headers.py; then echo "[static_scan] S10 ok" else - echo "[static_scan] S10 FAIL: 文件头存量见上清单(白名单清偿批在册)" + echo "[static_scan] S10 FAIL: 文件头存量见上清单" fail=1 fi diff --git a/tools/audit_file_headers.py b/tools/audit_file_headers.py index 3153e32d..5d8b1072 100644 --- a/tools/audit_file_headers.py +++ b/tools/audit_file_headers.py @@ -3,9 +3,8 @@ """audit_file_headers.py — 文件头机器闸(code-conventions §1.4.1)。 文件头 = .gd 文件顶部连续注释区:连续的空行或 # 注释行,首个非注释代码行止。 -本脚本只实现机械可判子集(两类白名单的人判面见规范正文): +本脚本只实现机械可判子集(2026-10-20 缩窄:行数上限 R1 与类别白名单已停用): R0 载体:头注非空时首行必须以 `##` 文档注释开头; - R1 行数上限:头注注释行(非空)> 8 行; R2 日期:头注出现日期模式(2026-09-12 / 2026年9月 一类)——日期只属于 git log 与迭代报告; R3 变更叙事词:「迭代N / 本迭代」、批次叙事复合词(本批/拆件批/改造批……)、「迁移到/改名为」 一类变更经过。清单从紧防误伤:「结算批」等玩法机制词不在黑名单; @@ -20,8 +19,6 @@ from pathlib import Path ROOT = Path(__file__).resolve().parent.parent SCAN_DIRS = ["game/core", "game/data", "game/presentation"] -MAX_HEADER_LINES = 8 - DATE_PAT = re.compile(r"\d{4}\s*[-/.年]\s*\d{1,2}") NARRATIVE_PATS = [ (re.compile(r"迭代\s*\d|本迭代"), "变更叙事「迭代N」"), @@ -52,9 +49,6 @@ def audit_path(path): rows = header_lines(text) if rows and not rows[0][1].lstrip().startswith("##"): hits.append((rows[0][0], "R0 头注必须以 ## 文档注释开头")) - if len(rows) > MAX_HEADER_LINES: - hits.append((rows[0][0], "R1 头注 %d 行 > 上限 %d 行(区间 %d-%d 行)" - % (len(rows), MAX_HEADER_LINES, rows[0][0], rows[-1][0]))) for lineno, line in rows: if DATE_PAT.search(line): hits.append((lineno, "R2 头注日期")) @@ -77,7 +71,7 @@ def main(): if violations: print("[audit_file_headers] FAIL: 文件头存量 %d 处(存量按 code-conventions §1.4.1 白名单清偿)" % violations) return 1 - print("[audit_file_headers] ok: 头注 ≤8 行且零黑名单命中") + print("[audit_file_headers] ok: 头注零黑名单命中(R0 载体/R2 日期/R3 变更叙事)") return 0 diff --git a/tools/doc_term_audit.py b/tools/doc_term_audit.py index 39a9ace7..b2bf485a 100644 --- a/tools/doc_term_audit.py +++ b/tools/doc_term_audit.py @@ -46,6 +46,8 @@ RETIRED_TERMS = [ ("雾格", "2026-09-14", "(雾格移除)", "不做清单"), ("兄弟精", "2026-09-26", "L2 熊地精(bugbear 复用)", "变体名未经批准退役批——用户质问查证后全仓清除"), # —— 用语规范(2026-10-15 用户令):权威=design/gdd/术语表.md「用语规范」A 表,机器闸吸收 —— + # 词表冻结:本节禁再新增词条;扩表唯一入口=用户实读反馈并经用户裁决,由非迭代批写入,agent 禁自行增词 + # (doc-conventions §4「词表冻结」)。 # 注意:「随批」「台账」两词本身是上方行级白名单信号(行内出现即归留档类),对其扫描会自豁免, # 故不列入;「收口」「在飞」等照常扫描。术语表「用语规范」节已加入节级豁免(词表自身不命中)。 ("对标", "2026-10-15", "参照", "用语规范 A 表(STC 1.7)"), diff --git a/tools/gdd_lint.py b/tools/gdd_lint.py index 03f9463d..de662260 100644 --- a/tools/gdd_lint.py +++ b/tools/gdd_lint.py @@ -9,7 +9,6 @@ r"""gdd_lint.py — GDD lean 格式门禁 规则(口径权威 = design/engineering/doc-conventions.md 第 5–6 节文档骨架与结构纪律): R1 散文段落 ≤ 240 字(代码块/表格/列表/引用不计) - R2 表格字符占比(词条表分域豁免,见 R2_EXEMPT 注) R3 正文禁止修订注记:~~删除线~~、"作废"、括号内"日期+评审/修订/拍板/裁决/核销" (登记处/清单按 RULE_EXEMPT 分域豁免) R4 禁止变更记录节:出现「版本历史/修订记录/变更记录/修改记录/更新记录/更新日志」标题即红 @@ -31,29 +30,18 @@ import sys from pathlib import Path MAX_PARA = 240 -# 2026-09-14 放宽 60→30:lean 改革后的新模板(参考 analysis/design 两件套)允许 -# 短段落与编号人话规则——防铺开的职责改由 R1(段 ≤240 字)与 R9(节点 ≤80 行)承担, -# R2 降为兜底下限(防纯散文文档)。 -MIN_TABLE_RATIO = 30 +# R2 表格占比判据已停用(2026-10-20 规则审阅批):lean 体系退役后其解读对象已不存在, +# 分域豁免越加越多、只产存量噪音(af94ce97 指纹刷新为证),判据与 R2_EXEMPT 一并拆除。 MAX_PAREN_SPAN = 80 -# 规则分域(2026-10-03 用户裁「测试要快/要准」优化批):R1/R2 的体裁前提是「规范文」 -# (短段+表格化);登记处/清单/概念文的自然形态就是长条目与叙事散文,硬套=自 2026-09-20 +# 规则分域(2026-10-03 用户裁「测试要快/要准」优化批):R1 的体裁前提是「规范文」 +# (短段+表格化);登记处/清单的自然形态就是长条目与叙事散文,硬套=自 2026-09-20 # 上线起 8/8 常红零过滤价值(test-perf-report-2026-10-02 §6.2 实证)。R3/R7 不豁免—— # 「provenance 出正文」对一切体裁有效;R4 变更记录节禁令自 2026-10-19 起对一切体裁有效。 R1_EXEMPT = { "06-待办清单.md", # 全项目待办登记处:现状/状态/方案长条目为体裁 "07-体验验证清单.md", # 体验验证读数清单:同上 } -R2_EXEMPT = { - "01-核心循环.md", # 循环概念文:叙事散文为体裁 - "03-内容规模.md", # 规模框架文:多维档位靠散文交代,结构表只有一张 - "04-美术音频方向.md", # 美术方向文:同上 - "05-不做清单.md", # 清单文:条目散文为体裁 - "06-待办清单.md", - "07-体验验证清单.md", - "术语表.md", # 词条表:表格为主体形态,表格占比高是体裁本身 -} # 规则粒度分域豁免(2026-10-15 用户令「清单类文件与术语表不做 GDD 规范性检查」)。 # 原则:**按规则豁免,不按文件拉黑**——体裁规则(R3/R5/R7)对登记处/清单/词条表 # 不适用,但机械可判的完整性规则(R4/R6/R8/R9/R11)一律不豁免,真缺陷不得藏起来。 @@ -201,17 +189,7 @@ def lint_file(path): if len(p) > MAX_PARA: issues.append(f"R1 散文段 {len(p)} 字(>{MAX_PARA}): {p[:50]}…") - # R2 表格占比(概念/方向/清单文分域豁免,见 R2_EXEMPT 注) - code_chars = sum(len(l) for l in code_lines) - table_chars = sum(len(l) for l in text.splitlines() if l.strip().startswith("|")) - total = max(len(text) - code_chars, 1) - ratio = int(100 * table_chars / total) - if fname in R2_EXEMPT: - infos.append(f"表格占比 {ratio}%(R2 分域豁免)") - elif ratio < MIN_TABLE_RATIO: - issues.append(f"R2 表格占比 {ratio}%(<{MIN_TABLE_RATIO}%)") - else: - infos.append(f"表格占比 {ratio}%") + # R2 表格占比已停用(见文件头注释)。 # R3 修订注记(代码块豁免;登记处/清单按 RULE_EXEMPT 豁免——变更记录节已整体禁设,无豁免域) body_no_code = "\n".join(l for l in text.splitlines() if l not in code_lines) @@ -307,7 +285,7 @@ def lint_file(path): issues.append(f"R7 最长括号跨度 {longest_span} 字(>{MAX_PAREN_SPAN})——疑似审计注记挤进正文") infos.append(f"最长括号跨度 {longest_span} 字") - return {"file": str(path), "issues": issues, "infos": infos, "table_ratio": ratio} + return {"file": str(path), "issues": issues, "infos": infos} def main(): @@ -347,7 +325,7 @@ def main(): else: for r in results: mark = "❌ FAIL" if r["issues"] else "✅ PASS" - print(f"\n{mark} {r['file']} (表格占比 {r['table_ratio']}%)") + print(f"\n{mark} {r['file']}") for i in r["infos"]: print(f" · {i}") for issue in r["issues"]: diff --git a/tools/pipeline_gate.py b/tools/pipeline_gate.py index fa5be310..47ed8a16 100644 --- a/tools/pipeline_gate.py +++ b/tools/pipeline_gate.py @@ -119,8 +119,12 @@ def check_title(title, line, issues, where): return face -def check_segment(word, creds, line, issues, where, root): - """判据 3 的单段校验。返回 (合法状态词|None, 已写卡路径|None, 已编迭代号|None)。""" +def check_segment(word, line, issues, where): + """判据 3 的单段校验。返回 (合法状态词|None, 已编迭代号|None)。 + + 2026-10-20 状态栏纯化批:状态行只写状态词(§12.1),括号凭据已废止—— + 闭合证据改到现状关联文档清单核对(check_todo 内),本函数只认状态词本身。 + """ def red(name, msg): issues.append((where, line, name, msg)) @@ -128,40 +132,24 @@ def check_segment(word, creds, line, issues, where, root): base = "已编迭代" if word.startswith("已编迭代") else word if im is None and base == "已编迭代": red("状态词非法", "「%s」缺迭代号(须「已编迭代 N」)" % word) - return None, None, None + return None, None if base not in STATUS_WORDS: - red("状态词非法", "「%s」不在合法状态词白名单" % word) - return None, None, None - cred_text = ";".join(creds) - if base in ("文档设计已闭合", "已写入"): - if not (VER_RE.search(cred_text) and ("/" in cred_text or ".md" in cred_text)): - red("凭据缺失", "「%s」须带括号落点凭据(文档路径+版本号形态)" % base) - elif base == "美术设计已闭合": - if not ("art-bible" in cred_text.lower() and VER_RE.search(cred_text)): - red("凭据缺失", "「美术设计已闭合」凭据须含 art-bible 路径+版本号") - elif base == "已写卡": - rp = None - for c in creds: - m = RESEARCH_RE.search(c) - if m: - rp = m.group(0) - break - if rp is None: - red("凭据缺失", "「已写卡」括号内须为 reports/ 下的需求卡片路径") - elif not (root / rp).is_file(): - red("卡片路径不存在", "已写卡路径 %s 相对仓库根不存在" % rp) - return base, rp, None + red("状态词非法", "「%s」不在合法状态词白名单" % base) + return None, None if im is not None: - return base, None, int(im.group(1)) - return base, None, None + return base, int(im.group(1)) + return base, None -def check_status(raw, line, face, issues, where, root): - """判据 3+状态段累积制(§12.1)+特批/备选。返回 (状态词列表, 已写卡路径列表, 已编迭代号|None)。 +def check_status(raw, line, face, issues, where): + """判据 3+状态段累积制(§12.1)+特批/备选。返回 (状态词列表, 已编迭代号|None)。 累积制:按+切段后段数不限,逐段各自合法;再查两条结构约束—— 下游段(待写卡/已写卡/已编迭代)在场时上游闭合段必须在场(带日期特批可豁免); 双轨设计阶段(无下游段)必须恰两段且一文档一美术。 + 状态行只写状态词(§12.1):去掉特批标记与(备选)后缀后,残留任何括号即红—— + 证据写现状关联文档清单,由 check_todo 到正文核对;此处点名病因后短路, + 不再产出碎片「状态词非法」误导红。 """ content = raw.strip() m = re.match(r"^\*\*(.+)\*\*$", content) @@ -175,28 +163,28 @@ def check_status(raw, line, face, issues, where, root): issues.append((where, line, "特批标记", "〔用户特批〕缺日期(带 YYYY-MM-DD 才放行跳轨)")) content = APPROVAL_RE.sub("", content) content = content.replace("(备选)", "").replace("(备选)", "").strip() + if re.search(r"[(())]", content): + issues.append((where, line, "状态行含括号内容", + "括号里的信息(路径/版本/说明)写进现状关联文档清单,状态行只留状态词(§12.1)")) + return [], None segs = [s.strip() for s in content.split("+") if s.strip()] if not segs: issues.append((where, line, "状态词非法", "状态行内容为空")) - return [], [], None - words, cards, iter_no = [], [], None + return [], None + words, iter_no = [], None for seg in segs: - creds = CRED_RE.findall(seg) - word = CRED_RE.sub("", seg).strip() - w, rp, it = check_segment(word, creds, line, issues, where, root) + w, it = check_segment(seg, line, issues, where) if w: words.append(w) - if rp: - cards.append(rp) if it is not None: iter_no = it downstream = [w for w in words if w in DOWNSTREAM_WORDS] if downstream and face in PRESENCE_FACES and not dated_approval: need = [] if face in ("文档轨", "双轨") and "文档设计已闭合" not in words: - need.append("文档设计已闭合(凭据)") + need.append("文档设计已闭合") if face in ("美术轨", "双轨") and "美术设计已闭合" not in words: - need.append("美术设计已闭合(凭据)") + need.append("美术设计已闭合") if need: issues.append((where, line, "在场约束", "下游段(%s)在场但缺上游闭合段 %s(带日期特批可豁免)" @@ -208,11 +196,16 @@ def check_status(raw, line, face, issues, where, root): issues.append((where, line, "双轨段数", "设计面=双轨设计阶段须恰两段且一文档一美术(现 %d 段:文档轨 %d、美术轨 %d)" % (len(segs), n_doc, n_art))) - return words, cards, iter_no + return words, iter_no def check_todo(text, issues, where, root): - """06 全部判据。返回交叉核链(已编迭代条目 → (行号, 迭代号, 卡片路径|None))。""" + """06 全部判据。返回交叉核链(已编迭代条目 → (行号, 迭代号, 卡片路径|None))。 + + 2026-10-20 状态栏纯化批:闭合类状态词的证据核对从状态栏括号改到现状关联文档 + 清单(§12.1「状态行只写状态词」)——已写卡对 reports/ 卡片路径+磁盘存在性, + 文档轨闭合/已写入对 design/ 路径+版本号,美术轨闭合对 art-bible+版本号。 + """ entries = parse_todo(text) links = [] if not entries: @@ -233,8 +226,45 @@ def check_todo(text, issues, where, root): issues.append((where, line, "属性缺失", "条目缺「**%s**」属性" % req)) if "状态" not in attrs: continue - words, cards, iter_no = check_status( - attrs["状态"], attr_line["状态"], face, issues, where, root) + words, iter_no = check_status( + attrs["状态"], attr_line["状态"], face, issues, where) + # 现状属性全文(含清单续行):证据核对只看现状,其他属性不算数 + xian_lines, in_xian = [], False + for ln, raw in e["body"]: + m = ATTR_LINE_RE.match(raw.strip()) + if m: + in_xian = m.group(1) == "现状" + if in_xian: + xian_lines.append(m.group(2)) + elif in_xian: + xian_lines.append(raw) + xian = "\n".join(xian_lines) + xline = attr_line.get("现状", line) + # 证据核对一:已写卡 → 现状清单须有卡片路径,逐条验磁盘存在 + cards = [] + if "已写卡" in words: + cards = RESEARCH_RE.findall(xian) + if not cards: + issues.append((where, xline, "正文缺卡片路径", + "状态段「已写卡」在场,但现状关联文档清单里没有 " + "reports/需求卡片-*.md 路径(§12.1:证据写正文)")) + else: + for rp in cards: + if not (root / rp).is_file(): + issues.append((where, line, "卡片路径不存在", + "现状清单里的卡片路径 %s 相对仓库根不存在" % rp)) + # 证据核对二:文档轨闭合/反哺已写入 → 现状清单须有文档路径+版本号 + # (06 正文里的指针是相对路径,形如 systems/… 或 design/…,只认 .md 收尾+版本号) + if "文档设计已闭合" in words or "已写入" in words: + if not (re.search(r"[^\s ,,()()]+\.md", xian) and VER_RE.search(xian)): + issues.append((where, xline, "正文缺设计定稿指针", + "状态段含文档轨闭合词,但现状清单里没有带版本号的文档路径(§12.1:证据写正文)")) + # 证据核对三:美术轨闭合 → 现状清单须有 art-bible 版本凭据 + if "美术设计已闭合" in words: + if not ("art-bible" in xian.lower() and VER_RE.search(xian)): + issues.append((where, xline, "正文缺美术凭据", + "状态段「美术设计已闭合」在场,但现状清单里没有 " + "art-bible 版本凭据(§12.1:证据写正文)")) need_gap = any(w in GAP_REQUIRED for w in words) if need_gap and "缺口" not in attrs: issues.append((where, line, "缺口属性", From b226a292dff5c546a40491e3578601d619322d21 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 23:19:40 +0800 Subject: [PATCH 36/59] =?UTF-8?q?test(=E5=8D=A1=E2=91=A1=20T7-F2):=20?= =?UTF-8?q?=E6=97=A7=E6=B5=8B=E8=AF=95=E6=96=AD=E8=A8=80=E9=9A=8F=E6=97=A0?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=8C=96=E6=8D=A2=E4=BB=A3=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=EF=BC=88smoke=20=E8=A3=B8=E5=BC=95=E6=93=8E=E6=AE=B5=20+=204?= =?UTF-8?q?=20=E5=8D=95=E6=B5=8B=E4=BB=B6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - smoke_all 裸引擎段 ~53 dispatch/写口 ctx 化、twin_digs→adv_twin_digs - _smoke_tree_rules:standalone 引擎自建 ctx、sense 限次跨战持久改 level 桶共享引用(删 export/seed 链) - effect_words_t1_test ⑥⑦重写为桶语义(adventure 共享字典往返、round_ 前缀随 round_start 整桶清空、battle 无前缀存活、counter_spend 静态) - tree_rules_v11_test 合成行夹具 lvl_ 改名+删 domain;treasure_effects/settle_segments dispatch/counter ctx 化、dig_combo→geo_types 活 id 冒烟 1150/0、四单测件 EXIT=0(换代同生死,无假绿)。 --- game/smoke/smoke_all.gd | 174 +++++++++--------- game/tests/unit/core/effect_words_t1_test.gd | 92 ++++----- game/tests/unit/core/settle_segments_test.gd | 4 +- game/tests/unit/core/treasure_effects_test.gd | 10 +- game/tests/unit/core/tree_rules_v11_test.gd | 12 +- 5 files changed, 150 insertions(+), 142 deletions(-) diff --git a/game/smoke/smoke_all.gd b/game/smoke/smoke_all.gd index ce2aba07..011a90e8 100644 --- a/game/smoke/smoke_all.gd +++ b/game/smoke/smoke_all.gd @@ -1422,188 +1422,188 @@ func _smoke_feats() -> void: for h in hits: if String(h.get("kind", "")) == "counter_add": var sv_c = h.get("set", null) - fx.counter_add(String(h.get("counter_id", "")), int(h.get("value", 0)) if sv_c == null else int(sv_c), sv_c != null) + EffectEngine.counter_add(orch.counters_ctx, String(h.get("counter_id", "")), int(h.get("value", 0)) if sv_c == null else int(sv_c), sv_c != null) # 开格系 fx.rebuild(["twin_pick"], [], []) for i in 4: - var hits_dp: Array = fx.dispatch("dig_paid", {"ap_cost": 1}) + var hits_dp: Array = fx.dispatch(orch.counters_ctx, "dig_paid", {"ap_cost": 1}) var refund := false for h in hits_dp: if String(h.get("kind", "")) == "grant_ap": refund = true - fx.counter_add("twin_digs", 1) + EffectEngine.counter_add(orch.counters_ctx, "adv_twin_digs", 1) if i == 1 or i == 3: check(refund, "双管镐:第 %d 次付费挖格返 1 AP(每第 2 次——mod_eq 预评估口径)" % (i + 1)) else: check(not refund, "双管镐反例:第 %d 次不返(未满 2 次)" % (i + 1)) fx.rebuild(["geologist"], [], []) - var geo_hits: Array = fx.dispatch("dig_reveal", {"new_resource_type": true}) + var geo_hits: Array = fx.dispatch(orch.counters_ctx, "dig_reveal", {"new_resource_type": true}) apply_fx.call(geo_hits) check(orch._hits_of(geo_hits, "counter_add").size() == 1, "地质学家:首开新类型集 1 点〔专长批 V3〕") - fx.counter_add("geo_types", 2) # 手动基数补齐(row1 已落账 1+2=3——满 4 种的预评估现值) - var geo_hits2: Array = fx.dispatch("dig_reveal", {"new_resource_type": true}) + EffectEngine.counter_add(orch.counters_ctx, "geo_types", 2) # 手动基数补齐(row1 已落账 1+2=3——满 4 种的预评估现值) + var geo_hits2: Array = fx.dispatch(orch.counters_ctx, "dig_reveal", {"new_resource_type": true}) apply_fx.call(geo_hits2) - check(orch._hits_of(geo_hits2, "reveal_tiles").size() == 1 and fx.counter("geo_types") == 0, + check(orch._hits_of(geo_hits2, "reveal_tiles").size() == 1 and EffectEngine.counter(orch.counters_ctx, "geo_types") == 0, "地质学家:满 4 种(预评估现值 3+本格)→揭示 1 格·计数清零〔专长批 V3〕") - var geo_hits3: Array = fx.dispatch("dig_reveal", {"new_resource_type": false}) + var geo_hits3: Array = fx.dispatch(orch.counters_ctx, "dig_reveal", {"new_resource_type": false}) check(orch._hits_of(geo_hits3, "counter_add").is_empty(), "地质学家反例:同类型重复首开不叠点〔专长批 V3〕") fx.rebuild(["hard_hat"], [], []) - apply_fx.call(fx.dispatch("dig_reveal", {})) - apply_fx.call(fx.dispatch("dig_reveal", {})) - check(fx.counter("helm_layers") == 2, "安全帽:开安全格攒层 ×2〔专长批 V3〕") - var hh_hits: Array = fx.dispatch("mine_hit", {"damage": 6}) + apply_fx.call(fx.dispatch(orch.counters_ctx, "dig_reveal", {})) + apply_fx.call(fx.dispatch(orch.counters_ctx, "dig_reveal", {})) + check(EffectEngine.counter(orch.counters_ctx, "helm_layers") == 2, "安全帽:开安全格攒层 ×2〔专长批 V3〕") + var hh_hits: Array = fx.dispatch(orch.counters_ctx, "mine_hit", {"damage": 6}) var hh_reduce := 0 for h in hh_hits: if String(h.get("kind", "")) == "damage_reduce": - hh_reduce = fx.counter(String(h.get("value_counter", ""))) + hh_reduce = EffectEngine.counter(orch.counters_ctx, String(h.get("value_counter", ""))) check(hh_reduce == 2, "安全帽:踩雷耗层减伤=层值 2(一次清零随施加面 set 行)〔专长批 V3〕") fx.rebuild(["skip_mining"], [], []) - var sk_zero: Array = fx.dispatch("dig_reveal", {"is_blank_zero": true}) + var sk_zero: Array = fx.dispatch(orch.counters_ctx, "dig_reveal", {"is_blank_zero": true}) apply_fx.call(sk_zero) check(orch._hits_of(sk_zero, "counter_add").size() == 1, "跳格采掘:空白 0 格攒 1 点〔专长批 V3〕") - fx.counter_add("skip_pts", 1) # 手动基数补齐(已落账 1+1=2——满 3 点的预评估现值) - var sk_full: Array = fx.dispatch("dig_reveal", {"is_blank_zero": true}) + EffectEngine.counter_add(orch.counters_ctx, "skip_pts", 1) # 手动基数补齐(已落账 1+1=2——满 3 点的预评估现值) + var sk_full: Array = fx.dispatch(orch.counters_ctx, "dig_reveal", {"is_blank_zero": true}) apply_fx.call(sk_full) check(orch._hits_of(sk_full, "reveal_tiles").size() == 1, "跳格采掘:满 3 点→揭示 1 格〔专长批 V3〕") - check(orch._hits_of(fx.dispatch("dig_reveal", {"is_blank_zero": false}), "counter_add").is_empty(), + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "dig_reveal", {"is_blank_zero": false}), "counter_add").is_empty(), "跳格采掘反例:普通开格不计点〔专长批 V3〕") fx.rebuild(["blast_accounting"], [], []) for i in 5: - var ba_hits: Array = fx.dispatch("dig_paid", {"ap_cost": 1}) + var ba_hits: Array = fx.dispatch(orch.counters_ctx, "dig_paid", {"ap_cost": 1}) for h in ba_hits: if String(h.get("kind", "")) == "counter_add": - fx.counter_add(String(h.get("counter_id", "")), 1) - check(orch._hits_of(fx.dispatch("round_end", {}), "grant_gp").size() == 1, "爆破会计:本轮挖格花费≥5→+1 GP〔专长批 V3〕") + EffectEngine.counter_add(orch.counters_ctx, String(h.get("counter_id", "")), 1) + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "round_end", {}), "grant_gp").size() == 1, "爆破会计:本轮挖格花费≥5→+1 GP〔专长批 V3〕") fx.rebuild(["frontier_miner"], [], []) - check(orch._hits_of(fx.dispatch("dig_reveal", {"is_edge_cell": true}), "grant_material").size() == 1 - and orch._hits_of(fx.dispatch("dig_reveal", {"is_edge_cell": false}), "grant_material").is_empty(), + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "dig_reveal", {"is_edge_cell": true}), "grant_material").size() == 1 + and orch._hits_of(fx.dispatch(orch.counters_ctx, "dig_reveal", {"is_edge_cell": false}), "grant_material").is_empty(), "边陲矿工:边缘格产出 +1·中心格反例零产出〔专长批 V3〕") # 封印系 fx.rebuild(["seal_echo"], [], []) - apply_fx.call(fx.dispatch("seal_hit", {})) - apply_fx.call(fx.dispatch("seal_hit", {})) - var se_hits: Array = fx.dispatch("round_end", {}) + apply_fx.call(fx.dispatch(orch.counters_ctx, "seal_hit", {})) + apply_fx.call(fx.dispatch(orch.counters_ctx, "seal_hit", {})) + var se_hits: Array = fx.dispatch(orch.counters_ctx, "round_end", {}) check(orch._hits_of(se_hits, "grant_ap").size() == 1 and String((orch._hits_of(se_hits, "grant_ap")[0] as Dictionary).get("mode", "")) == "queue", "封印回响:标中计数≥2→轮末返 1 AP(下轮 queue)〔专长批 V3〕") fx.rebuild(["seal_smith"], [], []) var sm_remove := 0 for i in 3: - var sm_dispatch: Array = fx.dispatch("seal_hit", {}) + var sm_dispatch: Array = fx.dispatch(orch.counters_ctx, "seal_hit", {}) apply_fx.call(sm_dispatch) for h in sm_dispatch: if String(h.get("kind", "")) == "remove_mines": sm_remove += 1 check(sm_remove == 1, "封印匠:标中每第 3 次→中立移除恰一次(频率闸死)〔专长批 V3〕") fx.rebuild(["seal_stake"], [], []) - check(orch._hits_of(fx.dispatch("seal_hit", {}), "ac_bonus").size() == 1 - and String((orch._hits_of(fx.dispatch("seal_hit", {}), "ac_bonus")[0] as Dictionary).get("mode", "")) == "round", + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "seal_hit", {}), "ac_bonus").size() == 1 + and String((orch._hits_of(fx.dispatch(orch.counters_ctx, "seal_hit", {}), "ac_bonus")[0] as Dictionary).get("mode", "")) == "round", "封印桩:标中本轮 AC +N(round 域——round_start 清零)〔专长批 V3〕") fx.rebuild(["warning_beacon"], [], []) - check(orch._hits_of(fx.dispatch("seal_hit", {}), "preview_area").size() == 1, "示警烟火:标中揭示 3×3 资源类型(不揭安危位置)〔专长批 V3〕") + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "seal_hit", {}), "preview_area").size() == 1, "示警烟火:标中揭示 3×3 资源类型(不揭安危位置)〔专长批 V3〕") # 踩雷/受伤系 fx.rebuild(["pain_memory"], [], []) - apply_fx.call(fx.dispatch("mine_hit", {})) - apply_fx.call(fx.dispatch("mine_hit", {})) - var pm_hits: Array = fx.dispatch("attack_commit", {"atk": 10, "target": "敌", "matchup": "", "dig_streak": 0, "nest_count": 0}) + apply_fx.call(fx.dispatch(orch.counters_ctx, "mine_hit", {})) + apply_fx.call(fx.dispatch(orch.counters_ctx, "mine_hit", {})) + var pm_hits: Array = fx.dispatch(orch.counters_ctx, "attack_commit", {"atk": 10, "target": "敌", "matchup": "", "dig_streak": 0, "nest_count": 0}) var pm_bonus := 0 for h in orch._hits_of(pm_hits, "attack_bonus"): - pm_bonus = fx.counter(String(h.get("value_counter", ""))) + pm_bonus = EffectEngine.counter(orch.counters_ctx, String(h.get("value_counter", ""))) check(pm_bonus == 2, "疼痛记忆:攻击附加层值伤害=层值 2·用后清零(set 行随施加面)〔专长批 V3〕") fx.rebuild(["fuse_wire"], [], []) - var fw_hits: Array = fx.dispatch("damage_taken", {"kind": "terrain", "amount": 6}) + var fw_hits: Array = fx.dispatch(orch.counters_ctx, "damage_taken", {"kind": "terrain", "amount": 6}) var fw_shield := 0 for h in fw_hits: if String(h.get("kind", "")) == "shield": fw_shield += int(h.get("value", 0)) - check(orch._hits_of(fx.dispatch("damage_taken", {"kind": "terrain", "amount": 3}), "shield").is_empty(), + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "damage_taken", {"kind": "terrain", "amount": 3}), "shield").is_empty(), "保险丝反例:单次 <5 不攒点不触发〔专长批 V3〕") - for h in fx.dispatch("damage_taken", {"kind": "terrain", "amount": 6}): + for h in fx.dispatch(orch.counters_ctx, "damage_taken", {"kind": "terrain", "amount": 6}): if String(h.get("kind", "")) == "counter_add": - fx.counter_add(String(h.get("counter_id", "")), int(h.get("value", 0))) + EffectEngine.counter_add(orch.counters_ctx, String(h.get("counter_id", "")), int(h.get("value", 0))) check(fw_shield == 0, "保险丝:首点不出盾(2 点才出——预评估口径)〔专长批 V3〕") fx.rebuild(["blood_insight"], [], []) - check(orch._hits_of(fx.dispatch("mine_hit", {}), "reveal_tiles").size() == 1, "见血开窍:踩雷揭示 1 格〔专长批 V3〕") + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "mine_hit", {}), "reveal_tiles").size() == 1, "见血开窍:踩雷揭示 1 格〔专长批 V3〕") fx.rebuild(["trap_instinct"], [], []) - apply_fx.call(fx.dispatch("mine_hit", {})) - var ti_hits: Array = fx.dispatch("attack_commit", {"atk": 10, "target": "敌", "matchup": "", "dig_streak": 0, "nest_count": 0}) + apply_fx.call(fx.dispatch(orch.counters_ctx, "mine_hit", {})) + var ti_hits: Array = fx.dispatch(orch.counters_ctx, "attack_commit", {"atk": 10, "target": "敌", "matchup": "", "dig_streak": 0, "nest_count": 0}) var ti_val := 0 for h in orch._hits_of(ti_hits, "attack_bonus"): - ti_val = fx.counter(String(h.get("value_counter", ""))) + ti_val = EffectEngine.counter(orch.counters_ctx, String(h.get("value_counter", ""))) check(ti_val == 2, "陷阱本能:踩雷本轮攻击 +2(attack_bonus 通道——面板加算)〔专长批 V3〕") fx.rebuild(["chain_traps", "pain_memory"], [], []) - apply_fx.call(fx.dispatch("mine_hit", {})) - var ct_before: int = fx.counter("pain_layers") - apply_fx.call(fx.dispatch("mine_hit", {})) - check(fx.counter("pain_layers") == ct_before + 2, "连环陷阱:同轮第 2 颗起每颗额外 +1 层(疼痛记忆同账)〔专长批 V3〕") + apply_fx.call(fx.dispatch(orch.counters_ctx, "mine_hit", {})) + var ct_before: int = EffectEngine.counter(orch.counters_ctx, "pain_layers") + apply_fx.call(fx.dispatch(orch.counters_ctx, "mine_hit", {})) + check(EffectEngine.counter(orch.counters_ctx, "pain_layers") == ct_before + 2, "连环陷阱:同轮第 2 颗起每颗额外 +1 层(疼痛记忆同账)〔专长批 V3〕") fx.rebuild(["trap_burst"], [], []) - var tb_hits: Array = fx.dispatch("mine_hit", {"damage": 8}) + var tb_hits: Array = fx.dispatch(orch.counters_ctx, "mine_hit", {"damage": 8}) check(orch._hits_of(tb_hits, "blast_scaled").size() == 1 and float((orch._hits_of(tb_hits, "blast_scaled")[0] as Dictionary).get("mult", 0)) > 1.0, "陷阱爆发:全体敌雷伤×倍率直伤(blast_scaled——施加面值=damage×mult)〔专长批 V3〕") fx.rebuild(["blood_honey"], [], []) - check(orch._hits_of(fx.dispatch("mine_hit", {}), "heal").size() == 1, "血蜜:踩雷回复 N 生命〔专长批 V3〕") + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "mine_hit", {}), "heal").size() == 1, "血蜜:踩雷回复 N 生命〔专长批 V3〕") fx.rebuild(["stone_skin"], [], []) - var ss_hits: Array = fx.dispatch("damage_taken", {"kind": "enemy_skill", "amount": 5, "source": "s", "round": 1}) + var ss_hits: Array = fx.dispatch(orch.counters_ctx, "damage_taken", {"kind": "enemy_skill", "amount": 5, "source": "s", "round": 1}) check(orch._hits_of(ss_hits, "ac_bonus").size() == 1 and int((orch._hits_of(ss_hits, "ac_bonus")[0] as Dictionary).get("cap", 0)) == 3, "石肤:受伤 AC+1(本场域 cap 3——达上限不再涨由累积器封顶)〔专长批 V3〕") fx.rebuild(["last_stand"], [], []) - check(orch._hits_of(fx.dispatch("damage_taken", {"kind": "enemy_skill", "amount": 5, "source": "s", "round": 1, "hp_ratio": 40}), "damage_reduce").size() == 1 - and orch._hits_of(fx.dispatch("damage_taken", {"kind": "enemy_skill", "amount": 5, "source": "s", "round": 2, "hp_ratio": 80}), "damage_reduce").is_empty(), + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "damage_taken", {"kind": "enemy_skill", "amount": 5, "source": "s", "round": 1, "hp_ratio": 40}), "damage_reduce").size() == 1 + and orch._hits_of(fx.dispatch(orch.counters_ctx, "damage_taken", {"kind": "enemy_skill", "amount": 5, "source": "s", "round": 2, "hp_ratio": 80}), "damage_reduce").is_empty(), "背水:生命≤50% 减伤·过半血反例零减伤〔专长批 V3〕") # 跨族桥 fx.rebuild(["breaker_strike"], [], []) - check(orch._hits_of(fx.dispatch("mine_hit", {"dug_under_seal": true}), "counter_add").size() == 1 - and orch._hits_of(fx.dispatch("mine_hit", {"dug_under_seal": false}), "counter_add").is_empty(), + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "mine_hit", {"dug_under_seal": true}), "counter_add").size() == 1 + and orch._hits_of(fx.dispatch(orch.counters_ctx, "mine_hit", {"dug_under_seal": false}), "counter_add").is_empty(), "破封一击:挖开带封印危险格 +1 层·无封印反例零触发〔专长批 V3〕") # 节奏系 fx.rebuild(["map_exchange"], [], []) - var me_hits: Array = fx.dispatch("dig_stop", {"ap_left": 4}) + var me_hits: Array = fx.dispatch(orch.counters_ctx, "dig_stop", {"ap_left": 4}) apply_fx.call(me_hits) - fx.counter_add("stop_swap", 4) # value_event="ap_left" 解析归施加面(action_economy 载荷取值)——冒烟手动落账 + EffectEngine.counter_add(orch.counters_ctx, "stop_swap", 4) # value_event="ap_left" 解析归施加面(action_economy 载荷取值)——冒烟手动落账 check(orch._hits_of(me_hits, "counter_add").size() == 1, "弃图兑换:停手剩余 AP≥3 入账〔专长批 V3〕") var me_atk := 0 - for h in orch._hits_of(fx.dispatch("attack_commit", {"atk": 10, "target": "敌", "matchup": "", "dig_streak": 0, "nest_count": 0}), "attack_bonus"): - me_atk = fx.counter(String(h.get("value_counter", ""))) + for h in orch._hits_of(fx.dispatch(orch.counters_ctx, "attack_commit", {"atk": 10, "target": "敌", "matchup": "", "dig_streak": 0, "nest_count": 0}), "attack_bonus"): + me_atk = EffectEngine.counter(orch.counters_ctx, String(h.get("value_counter", ""))) check(me_atk == 4, "弃图兑换:折为攻击伤害=剩余 AP 全额·用后清零〔专长批 V3〕") - check(orch._hits_of(fx.dispatch("dig_stop", {"ap_left": 2}), "counter_add").is_empty(), + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "dig_stop", {"ap_left": 2}), "counter_add").is_empty(), "弃图兑换反例:剩余 AP<3 不触发〔专长批 V3〕") fx.rebuild(["last_drop"], [], []) - var ld_hits: Array = fx.dispatch("round_start", {"round": 2, "ap_exhausted_last": true}) + var ld_hits: Array = fx.dispatch(orch.counters_ctx, "round_start", {"round": 2, "ap_exhausted_last": true}) check(orch._hits_of(ld_hits, "grant_ap").size() == 1, "一滴不剩:上轮 AP 耗尽→+1 AP〔专长批 V3〕") - check(orch._hits_of(fx.dispatch("round_start", {"round": 3, "ap_exhausted_last": false}), "grant_ap").is_empty(), + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "round_start", {"round": 3, "ap_exhausted_last": false}), "grant_ap").is_empty(), "一滴不剩反例:上轮有余不发〔专长批 V3〕") fx.rebuild(["market_close"], [], []) for i in 8: - for h in fx.dispatch("dig_reveal", {}): + for h in fx.dispatch(orch.counters_ctx, "dig_reveal", {}): if String(h.get("kind", "")) == "counter_add": - fx.counter_add(String(h.get("counter_id", "")), 1) - check(orch._hits_of(fx.dispatch("round_end", {}), "grant_gp").size() == 1, "收盘:本轮开格≥8→+1 GP〔专长批 V3〕") + EffectEngine.counter_add(orch.counters_ctx, String(h.get("counter_id", "")), 1) + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "round_end", {}), "grant_gp").size() == 1, "收盘:本轮开格≥8→+1 GP〔专长批 V3〕") # 战斗系 fx.rebuild(["execution_scholar"], [], []) - check(orch._hits_of(fx.dispatch("kill", {"target": "敌", "overflow": 0}), "reveal_tiles").size() == 1, + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "kill", {"target": "敌", "overflow": 0}), "reveal_tiles").size() == 1, "斩首学者:击杀揭示 1 格〔专长批 V3〕") fx.rebuild(["executioner"], [], []) - var ex_hits: Array = fx.dispatch("enemy_hp_threshold", {"unit": "e1", "pct": 30, "is_boss": false}) + var ex_hits: Array = fx.dispatch(orch.counters_ctx, "enemy_hp_threshold", {"unit": "e1", "pct": 30, "is_boss": false}) check(orch._hits_of(ex_hits, "target_attack_bonus").size() == 1 - and orch._hits_of(fx.dispatch("enemy_hp_threshold", {"unit": "e1", "pct": 60, "is_boss": false}), "target_attack_bonus").is_empty(), + and orch._hits_of(fx.dispatch(orch.counters_ctx, "enemy_hp_threshold", {"unit": "e1", "pct": 60, "is_boss": false}), "target_attack_bonus").is_empty(), "处刑台:敌血量≤30% 挂单位标记加伤·阈值外反例零命中〔专长批 V3〕") fx.rebuild(["field_dressing"], [], []) - check(orch._hits_of(fx.dispatch("battle_won", {"round": 2}), "heal").size() == 1, + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "battle_won", {"round": 2}), "heal").size() == 1, "战地包扎:战斗胜利回复 N 生命(battle_won 新挂点)〔专长批 V3〕") # 契约尖点 fx.rebuild(["blood_tax"], [], []) - check(orch._hits_of(fx.dispatch("mine_hit", {}), "bonus_delta").size() == 1 - and String((orch._hits_of(fx.dispatch("seal_hit", {}), "bonus_delta")[0] as Dictionary).get("axis", "")) == "atk", + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "mine_hit", {}), "bonus_delta").size() == 1 + and String((orch._hits_of(fx.dispatch(orch.counters_ctx, "seal_hit", {}), "bonus_delta")[0] as Dictionary).get("axis", "")) == "atk", "血税:双向同局账本(踩陷阱−2max_hp/封印命中+1atk——bonus_delta 战末汇入)〔专长批 V3〕") # 迁入 2 件 fx.rebuild(["venom_edge"], [], []) - check(orch._hits_of(fx.dispatch("clamp_check", {"matchup": "magic_vs_heavy"}), "modify_ticket").size() == 1 - and orch._hits_of(fx.dispatch("clamp_check", {"matchup": "normal_vs_light"}), "modify_ticket").is_empty(), + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "clamp_check", {"matchup": "magic_vs_heavy"}), "modify_ticket").size() == 1 + and orch._hits_of(fx.dispatch(orch.counters_ctx, "clamp_check", {"matchup": "normal_vs_light"}), "modify_ticket").is_empty(), "淬毒刃纹(迁入):克制正面(magic_vs_heavy 矩阵值>0)追加·中性面反例零触发〔专长批 V3〕") fx.rebuild(["seal_burst"], [], []) - check(orch._hits_of(fx.dispatch("seal_hit", {}), "open_ticket").size() == 1, + check(orch._hits_of(fx.dispatch(orch.counters_ctx, "seal_hit", {}), "open_ticket").size() == 1, "封印爆裂(迁入):标中全体敌群伤〔专长批 V3〕") # 零持有 var orch0 = load("res://core/battle_orchestrator.gd").new(_db, _fresh_rng(74)) @@ -6051,36 +6051,40 @@ func _smoke_tree() -> void: # 引擎直构 + 编排授予段直注(_grant_seg._judge_seal=结算授予段封印判定单口))---- func _smoke_tree_rules() -> void: print("--- 天赋树六键行为(V10:窗/限次/聚散/守侧)---") - # 开局姿态组:每关首轮窗(battle_index 事实——引擎直构) + # 开局姿态组:每关首轮窗(battle_index 事实——引擎直构 + 自建 ctx) var fx = load("res://core/effect_engine.gd").new(null) fx.rebuild([], [], ["posture_first_strike", "posture_bulwark"]) - check((fx.dispatch("round_start", {"battle_index": 1, "round_index": 1}, Callable()) as Array).size() == 1, + var ctx_p := EffectContext.new() + check((fx.dispatch(ctx_p, "round_start", {"battle_index": 1, "round_index": 1}, Callable()) as Array).size() == 1, "先手压制:每关首战首轮窗命中(battle_index=1 且 round=1 → grant_ap queue)〔天赋树批 V10〕") - check((fx.dispatch("round_start", {"battle_index": 1, "round_index": 2}, Callable()) as Array).is_empty() - and (fx.dispatch("round_start", {"battle_index": 2, "round_index": 1}, Callable()) as Array).is_empty(), + check((fx.dispatch(ctx_p, "round_start", {"battle_index": 1, "round_index": 2}, Callable()) as Array).is_empty() + and (fx.dispatch(ctx_p, "round_start", {"battle_index": 2, "round_index": 1}, Callable()) as Array).is_empty(), "先手压制:首轮窗外地不触发(第二轮/第二关首战首轮——「每战首轮」旧语义换代件)") - check((fx.dispatch("damage_taken", {"battle_index": 1, "round_index": 1}, Callable()) as Array).size() == 1 - and (fx.dispatch("damage_taken", {"battle_index": 2, "round_index": 1}, Callable()) as Array).is_empty(), + check((fx.dispatch(ctx_p, "damage_taken", {"battle_index": 1, "round_index": 1}, Callable()) as Array).size() == 1 + and (fx.dispatch(ctx_p, "damage_taken", {"battle_index": 2, "round_index": 1}, Callable()) as Array).is_empty(), "稳健拓荒:首轮窗内受击出盾、窗外不出(shield damage_taken 同窗条件)") - # 危险直觉·锋:限次闸(引擎直构——mine_hit 挂点现成,编排收集 halve_pct 系既有 damage_mult 路径) + # 危险直觉·锋:限次闸(引擎直构——mine_hit 挂点现成;限次计数住 level 桶,跨战持久=共享同一字典引用) var fz = load("res://core/effect_engine.gd").new(null) fz.rebuild([], [], ["sense_sharp"]) + var lvl_shared := {} # 同一关的 level 桶(两编排器共享引用 = 跨战持久,替代旧 counters_export/seed 副本搬运) + var ctx_fz := EffectContext.new() + ctx_fz.level_bucket = lvl_shared var got_mult := false var got_add := false - for h in (fz.dispatch("mine_hit", {}, Callable()) as Array): + for h in (fz.dispatch(ctx_fz, "mine_hit", {}, Callable()) as Array): if String(h.get("kind", "")) == "damage_mult": got_mult = true if String(h.get("kind", "")) == "counter_add": got_add = true check(got_mult and got_add, "锋:踩雷减半命中+限次记账(counter 0<2 闸开——damage_mult+counter_add 双行同预评估态)") - fz.counter_add("tree_sense_sharp_used", 2) # 直调置数(V10 注入口径——置关卡域计数后走事件路径) - check((fz.dispatch("mine_hit", {}, Callable()) as Array).is_empty(), "锋:限次耗尽全额(counter 2 不<2 闸关——每关限次 provisional 2)") - var exported: Dictionary = fz.counters_export() + EffectEngine.counter_add(ctx_fz, "lvl_tree_sense_sharp_used", 2) # 直调置数(V10 注入口径——置 level 桶计数后走事件路径) + check((fz.dispatch(ctx_fz, "mine_hit", {}, Callable()) as Array).is_empty(), "锋:限次耗尽全额(counter 2 不<2 闸关——每关限次 provisional 2)") var fz2 = load("res://core/effect_engine.gd").new(null) fz2.rebuild([], [], ["sense_sharp"]) - fz2.counters_seed(exported) - check((fz2.dispatch("mine_hit", {}, Callable()) as Array).is_empty(), - "锋:限次跨战持久(adventure 域 counters_export/seed——断点保留同源,不新增存档域不升 v7)") + var ctx_fz2 := EffectContext.new() + ctx_fz2.level_bucket = lvl_shared # 挂同一 level 桶引用(新形态跨战持久:无 export/seed,同字典即持久) + check((fz2.dispatch(ctx_fz2, "mine_hit", {}, Callable()) as Array).is_empty(), + "锋:限次跨战持久(level 桶共享引用——替代旧 adventure 域 counters_export/seed 副本搬运)") # 守侧五场景(契约 12):编排 rig——begin_battle 携 sense_guard,授予段 _grant_seg._judge_seal 直注 var orch = load("res://core/battle_orchestrator.gd").new(_db, _fresh_rng(777001)) check(orch.begin_battle({"level_index": 1, "node_depth": 0, "hero_hp": 40, "hero_atk": 8, "hero_max_hp": 40, diff --git a/game/tests/unit/core/effect_words_t1_test.gd b/game/tests/unit/core/effect_words_t1_test.gd index a40634ad..bd2af281 100644 --- a/game/tests/unit/core/effect_words_t1_test.gd +++ b/game/tests/unit/core/effect_words_t1_test.gd @@ -26,12 +26,12 @@ func _init() -> void: "新效果类型在册:heal/ac_bonus/damage_reduce/bonus_delta/blast_scaled/preview_area/target_attack_bonus〔专长批 V1〕") Kit.check_quiet(EffectEngineScript.OPS.has("mod_eq"), "新算子在册:mod_eq〔专长批 V1〕") - # ② 合法新词行零违例(validate_trigger_row 正例) + # ② 合法新词行零违例(validate_trigger_row 正例——前缀归属替代旧 domain 键) var errs: Array = [] var ok_row := {"on": "dig_stop", "when": [{"fact": "ap_left", "op": "gte", "value": 3}], - "do": {"kind": "counter_add", "counter_id": "stop_swap", "value_event": "ap_left", "domain": "adventure"}} + "do": {"kind": "counter_add", "counter_id": "stop_swap", "value_event": "ap_left"}} var mine_covered: bool = EffectEngineScript.validate_trigger_row("V1正例", {}, [ok_row], errs) - Kit.check_quiet(errs.is_empty() and not mine_covered, "合法新词行 validate 零违例(dig_stop/ap_left/counter_add+domain)〔专长批 V1〕") + Kit.check_quiet(errs.is_empty() and not mine_covered, "合法新词行 validate 零违例(dig_stop/ap_left/counter_add——battle 桶无前缀)〔专长批 V1〕") errs = [] EffectEngineScript.validate_trigger_row("V1正例2", {}, [{"on": "battle_won", "when": [{"fact": "hp_ratio", "op": "lte", "value": 1}], @@ -46,81 +46,85 @@ func _init() -> void: EffectEngineScript.validate_trigger_row("出域kind", {}, [{"on": "dig_stop", "do": {"kind": "nope_kind", "value": 1}}], errs) Kit.check_quiet(errs.size() == 4, "出域 on/fact/op/kind 各一行全部被拒(4 违例)〔专长批 V1〕") - # ④ 运行期命中序(合法新事件;dispatch 出域 fail-fast=debug assert〔effect_engine dispatch 首行 - # assert(EVENTS.has)——release 剥离系引擎语义,自动化覆盖走 ③ 加载期 validate 致命通道〕) + # ④ 运行期命中序(合法新事件;dispatch 出域 fail-fast=debug assert;引擎无状态——计数器经 ctx) var fx = EffectEngineScript.new(null) + var ctx_f := EffectContext.new() var hits: Array = [] fx.rebuild([], [], []) fx._push_trigger("test", "v1_row", {"on": "dig_stop", "when": [{"fact": "ap_left", "op": "gte", "value": 3}], "do": {"kind": "counter_add", "counter_id": "stop_swap", "value_event": "ap_left"}}, {}) - hits = fx.dispatch("dig_stop", {"ap_left": 5}) + hits = fx.dispatch(ctx_f, "dig_stop", {"ap_left": 5}) Kit.check_quiet(hits.size() == 1, "dig_stop 合法命中(ap_left 5≥3)〔专长批 V1〕") - hits = fx.dispatch("dig_stop", {"ap_left": 1}) + hits = fx.dispatch(ctx_f, "dig_stop", {"ap_left": 1}) Kit.check_quiet(hits.is_empty(), "dig_stop 反例不命中(ap_left 1<3)〔专长批 V1〕") Kit.check_quiet(not EffectEngineScript.EVENTS.has("dig_stop_x"), "词表封闭:出域事件词不在 EVENTS(dispatch 首行 assert 消费同一词表)〔专长批 V1〕") - # ⑤ mod_eq 算子(双管镐落法——预评估口径每第 2 次判定) + # ⑤ mod_eq 算子(双管镐落法——预评估口径每第 2 次判定;battle 桶无前缀) var fx2 = EffectEngineScript.new(null) + var ctx2 := EffectContext.new() fx2.rebuild([], [], []) fx2._push_trigger("test", "mod_row", {"on": "dig_paid", "when": [{"fact": "counter", "id": "dbl_digs", "op": "mod_eq", "value": 2, "ref": 1}], "do": {"kind": "grant_ap", "value": 1}}, {}) var refunds := 0 for i in 4: - if not fx2.dispatch("dig_paid", {"ap_cost": 1}).is_empty(): + if not fx2.dispatch(ctx2, "dig_paid", {"ap_cost": 1}).is_empty(): refunds += 1 - fx2.counter_add("dbl_digs", 1) + EffectEngine.counter_add(ctx2, "dbl_digs", 1) Kit.check_quiet(refunds == 2, "mod_eq 预评估口径:4 次付费挖格恰返 2 次(第 2/4 次)〔专长批 V1〕") - # ⑥ adventure 域计数器 export/seed 往返(T6) + # ⑥ adventure 桶共享引用跨引擎持久(T6 换代——替代旧 export/seed 副本搬运) + var adv_bucket := {} # 同一冒险账本字典引用跨两引擎=跨战持久(无副本无搬运时点) var fx3 = EffectEngineScript.new(null) fx3._push_trigger("test", "adv_row", {"on": "mine_hit", - "do": {"kind": "counter_add", "counter_id": "pain_layers", "value": 1, "domain": "adventure"}}, {}) - fx3._push_trigger("test", "adv_row2", {"on": "mine_hit", - "do": {"kind": "counter_add", "counter_id": "round_mines", "value": 1, "reset_at": "round_start"}}, {}) + "do": {"kind": "counter_add", "counter_id": "adv_persist", "value": 1}}, {}) + var ctx3 := EffectContext.new() + ctx3.adventure_bucket = adv_bucket for _i in 2: - for h in fx3.dispatch("mine_hit", {}): # 施加面同构(编排侧 counter_add 逐条落账) + for h in fx3.dispatch(ctx3, "mine_hit", {}): if String(h.get("kind", "")) == "counter_add": - fx3.counter_add(String(h.get("counter_id", "")), int(h.get("value", 0))) - var exported: Dictionary = fx3.counters_export() - Kit.check_quiet(exported.get("pain_layers", -1) == 2 and not exported.has("round_mines"), - "export 只含 adventure 域(pain_layers=2、round_mines battle 域不入)〔专长批 V1〕") + EffectEngine.counter_add(ctx3, String(h.get("counter_id", "")), int(h.get("value", 0))) + Kit.check_quiet(EffectEngine.counter(ctx3, "adv_persist") == 2 and int(adv_bucket.get("adv_persist", -1)) == 2, + "adventure 桶就地直写共享字典累积=2(adv_ 前缀归 adventure 桶——替代旧 counters_export)〔专长批 V1〕") var fx4 = EffectEngineScript.new(null) - fx4._push_trigger("test", "adv_row_seed", {"on": "mine_hit", - "do": {"kind": "counter_add", "counter_id": "pain_layers", "value": 1, "domain": "adventure"}}, {}) - fx4.counters_seed({"pain_layers": 7}) - Kit.check_quiet(fx4.counter("pain_layers") == 7, "seed 回灌:counters_seed 后 adventure 域计数器=7〔专长批 V1〕") + fx4._push_trigger("test", "adv_row2", {"on": "mine_hit", + "do": {"kind": "counter_add", "counter_id": "adv_persist", "value": 1}}, {}) + var ctx4 := EffectContext.new() + ctx4.adventure_bucket = adv_bucket # 挂同一字典引用=下一战可读上一战持久值(替代旧 counters_seed 回灌) + Kit.check_quiet(EffectEngine.counter(ctx4, "adv_persist") == 2, + "adventure 桶共享引用跨引擎可读(无 export/seed,同字典即跨战持久)〔专长批 V1〕") - # ⑦ V4——攒层/计数类件跨事件计数(置计数→事件路径→清零点:round_start 重置/用后清零) + # ⑦ V4——前缀归桶清零/消耗语义(round_ 桶随 round_start 整桶清空;battle 无前缀计数跨 round_start 存活) var fx5 = EffectEngineScript.new(null) + var ctx5 := EffectContext.new() fx5.rebuild([], [], []) fx5._push_trigger("test", "round_row", {"on": "mine_hit", - "do": {"kind": "counter_add", "counter_id": "round_mines", "value": 1}}, {}) # 未声明 reset_at——round_start 不重置(声明制对照面) - fx5._push_trigger("test", "spend_row", {"on": "treasure_used", - "do": {"kind": "counter_spend", "counter_id": "round_mines", "value": 1}}, {}) - for h in fx5.dispatch("mine_hit", {}): + "do": {"kind": "counter_add", "counter_id": "round_mines", "value": 1}}, {}) + for h in fx5.dispatch(ctx5, "mine_hit", {}): if String(h.get("kind", "")) == "counter_add": - fx5.counter_add(String(h.get("counter_id", "")), int(h.get("value", 0))) - for h in fx5.dispatch("mine_hit", {}): + EffectEngine.counter_add(ctx5, String(h.get("counter_id", "")), int(h.get("value", 0))) + for h in fx5.dispatch(ctx5, "mine_hit", {}): if String(h.get("kind", "")) == "counter_add": - fx5.counter_add(String(h.get("counter_id", "")), int(h.get("value", 0))) - Kit.check_quiet(fx5.counter("round_mines") == 2, "V4:跨事件计数累积(两雷两计)〔专长批 V4〕") - Kit.check_quiet(fx5.counter_spend("round_mines", 1) and fx5.counter("round_mines") == 1, - "V4:counter_spend 写口消耗(用后清零语义承载面)〔专长批 V4〕") - fx5.dispatch("round_start", {"round": 2}) - Kit.check_quiet(fx5.counter("round_mines") == 1, - "V4:非 reset 点计数器不受 round_start 影响(reset_at 声明制——round_mines 未声明重置)〔专长批 V4〕") + EffectEngine.counter_add(ctx5, String(h.get("counter_id", "")), int(h.get("value", 0))) + Kit.check_quiet(EffectEngine.counter(ctx5, "round_mines") == 2, "V4:跨事件计数累积(两雷两计——round_ 前缀落 round 桶)〔专长批 V4〕") + Kit.check_quiet(EffectEngine.counter_spend(ctx5, "round_mines", 1) and EffectEngine.counter(ctx5, "round_mines") == 1, + "V4:counter_spend 静态写口消耗(用后清零语义承载面)〔专长批 V4〕") + fx5.dispatch(ctx5, "round_start", {"round": 2}) + Kit.check_quiet(EffectEngine.counter(ctx5, "round_mines") == 0, + "V4:round_ 前缀计数器随 round_start 整桶清空(旧 reset_at 名单声明制换代为前缀归桶)〔专长批 V4〕") + # battle 桶对照:无前缀 helm_layers 不受 round_start 影响(跨 round_start 存活) var fx6 = EffectEngineScript.new(null) + var ctx6 := EffectContext.new() fx6.rebuild([], [], []) - fx6._push_trigger("test", "reset_row", {"on": "mine_hit", - "do": {"kind": "counter_add", "counter_id": "helm_layers", "value": 1, "reset_at": "round_start"}}, {}) - for h in fx6.dispatch("mine_hit", {}): + fx6._push_trigger("test", "battle_row", {"on": "mine_hit", + "do": {"kind": "counter_add", "counter_id": "helm_layers", "value": 1}}, {}) + for h in fx6.dispatch(ctx6, "mine_hit", {}): if String(h.get("kind", "")) == "counter_add": - fx6.counter_add(String(h.get("counter_id", "")), int(h.get("value", 0))) - fx6.dispatch("round_start", {"round": 2}) - Kit.check_quiet(fx6.counter("helm_layers") == 0, - "V4:round_start 重置点清零(订阅行声明 reset_at——安全帽攒层清零语义)〔专长批 V4〕") + EffectEngine.counter_add(ctx6, String(h.get("counter_id", "")), int(h.get("value", 0))) + fx6.dispatch(ctx6, "round_start", {"round": 2}) + Kit.check_quiet(EffectEngine.counter(ctx6, "helm_layers") == 1, + "V4:battle 桶(无前缀)计数器不受 round_start 清空(round 桶整桶清空仅触及 round_ 前缀键)〔专长批 V4〕") quit(Kit.finish("effect_words_t1")) diff --git a/game/tests/unit/core/settle_segments_test.gd b/game/tests/unit/core/settle_segments_test.gd index 53c419db..68da98a1 100644 --- a/game/tests/unit/core/settle_segments_test.gd +++ b/game/tests/unit/core/settle_segments_test.gd @@ -29,8 +29,8 @@ func _init() -> void: Kit.check_quiet(oc._combat_seg != null and oc._combat_seg.oc == oc, "V4 编排器接线·战斗段〔迭代27 T2〕") Kit.check_quiet(oc._decay_seg != null and oc._decay_seg.oc == oc, "V4 编排器接线·衰减段〔迭代27 T2〕") Kit.check_quiet(oc._verdict_seg != null and oc._verdict_seg.oc == oc, "V4 编排器接线·判定段〔迭代27 T2〕") - Kit.check_quiet(oc._grant_seg._apply_counter_hit({"counter_id": "dig_combo", "value": 1}) == null - and oc._fx.counter("dig_combo") == 1, "V4 counter_add 助手单点(原五位三行组收拢后行为等价)〔迭代27 T2〕") + Kit.check_quiet(oc._grant_seg._apply_counter_hit({"counter_id": "geo_types", "value": 1}) == null + and EffectEngine.counter(oc.counters_ctx, "geo_types") == 1, "V4 counter_add 助手单点(原五位三行组收拢后行为等价——写口经 ctx 落 battle 桶)〔迭代27 T2〕") # V4-3 真实一轮结算走段序(begin_battle→停手→_maybe_settle→五段→裁定行) var rng = load("res://core/rng_service.gd").new() diff --git a/game/tests/unit/core/treasure_effects_test.gd b/game/tests/unit/core/treasure_effects_test.gd index e98f59e6..95fbd150 100644 --- a/game/tests/unit/core/treasure_effects_test.gd +++ b/game/tests/unit/core/treasure_effects_test.gd @@ -31,7 +31,7 @@ func _init() -> void: var ap_with := int(ob1.action_economy._ap) # 测试夹具直读(呈现读数走 presentation_snapshot——本断言取账本真值) Kit.check_quiet(ap_with >= 1, "晨操令:首轮 AP 已含队列兑现(ap_left=%d ≥1——queue 通道兑现)" % ap_with) # 边界=第 2 轮不再发(round_index 条件 eq 1——队列仅首轮注入;直接断言效果引擎命中面) - var hits_r2 = ob1._fx.dispatch("round_start", {"round_index": 2}) + var hits_r2 = ob1._fx.dispatch(ob1.counters_ctx, "round_start", {"round_index": 2}) var r2_ap := 0 for h in hits_r2: if String(h.get("kind", "")) == "grant_ap" and String(h.get("mode", "")) == "queue": @@ -42,7 +42,7 @@ func _init() -> void: var ob1b = orch_s.new(db, rng1b) Kit.check_quiet(ob1b.begin_battle({"level_index": 1, "node_depth": 0, "hero_hp": int(db.hero.max_hp)}) and ob1b.attune_param_sum("light_radius_bonus") == 0, "空装配基线复用:未装配件参数读数 0") - var hits_none = ob1b._fx.dispatch("round_start", {"round_index": 1}) + var hits_none = ob1b._fx.dispatch(ob1b.counters_ctx, "round_start", {"round_index": 1}) Kit.check_quiet(_ap_of(hits_none) == 0, "晨操令反例:未装配首轮零命中(订阅行随装配集装载)") # ② 双管装填(前 2 轮各 +1 / 第 3 轮零) @@ -50,10 +50,10 @@ func _init() -> void: var ob2 = orch_s.new(db, rng2) Kit.check_quiet(ob2.begin_battle({"level_index": 1, "node_depth": 0, "hero_hp": int(db.hero.max_hp), "attunement": ["twin_loader"]}), "双管装填:装配起战") - Kit.check_quiet(_ap_of(ob2._fx.dispatch("round_start", {"round_index": 1})) == 1 - and _ap_of(ob2._fx.dispatch("round_start", {"round_index": 2})) == 1, + Kit.check_quiet(_ap_of(ob2._fx.dispatch(ob2.counters_ctx, "round_start", {"round_index": 1})) == 1 + and _ap_of(ob2._fx.dispatch(ob2.counters_ctx, "round_start", {"round_index": 2})) == 1, "双管装填:第 1/2 轮各命中 +1(lte 2 边界内)") - Kit.check_quiet(_ap_of(ob2._fx.dispatch("round_start", {"round_index": 3})) == 0, + Kit.check_quiet(_ap_of(ob2._fx.dispatch(ob2.counters_ctx, "round_start", {"round_index": 3})) == 0, "双管装填反例:第 3 轮零命中;战斗外零发放(round_start 事件域外无触发面)") # ③ 阔视野带(参数读数=4 / 未装配=0——注入面消费在呈现桥 T4) diff --git a/game/tests/unit/core/tree_rules_v11_test.gd b/game/tests/unit/core/tree_rules_v11_test.gd index 3e88d9e6..cdda06cf 100644 --- a/game/tests/unit/core/tree_rules_v11_test.gd +++ b/game/tests/unit/core/tree_rules_v11_test.gd @@ -26,17 +26,17 @@ func _init() -> void: {"fact": "round_index", "op": "eq", "value": 1}], "do": {"kind": "shield", "value": 1}}], "sense_sharp": [{"on": "mine_hit", - "when": [{"fact": "counter", "id": "tree_sense_sharp_used", "op": "lt", "value": 2}], + "when": [{"fact": "counter", "id": "lvl_tree_sense_sharp_used", "op": "lt", "value": 2}], "do": {"kind": "damage_mult", "value": 50}}, {"on": "mine_hit", - "when": [{"fact": "counter", "id": "tree_sense_sharp_used", "op": "lt", "value": 2}], - "do": {"kind": "counter_add", "counter_id": "tree_sense_sharp_used", "value": 1, "domain": "adventure"}}], + "when": [{"fact": "counter", "id": "lvl_tree_sense_sharp_used", "op": "lt", "value": 2}], + "do": {"kind": "counter_add", "counter_id": "lvl_tree_sense_sharp_used", "value": 1}}], "sense_guard": [{"on": "seal_missed", - "when": [{"fact": "counter", "id": "tree_sense_guard_used", "op": "lt", "value": 2}], + "when": [{"fact": "counter", "id": "lvl_tree_sense_guard_used", "op": "lt", "value": 2}], "do": {"kind": "grant_ap", "mode": "queue", "value": 1}}, {"on": "seal_missed", - "when": [{"fact": "counter", "id": "tree_sense_guard_used", "op": "lt", "value": 2}], - "do": {"kind": "counter_add", "counter_id": "tree_sense_guard_used", "value": 1, "domain": "adventure"}}], + "when": [{"fact": "counter", "id": "lvl_tree_sense_guard_used", "op": "lt", "value": 2}], + "do": {"kind": "counter_add", "counter_id": "lvl_tree_sense_guard_used", "value": 1}}], } var six := ["posture_first_strike", "posture_bulwark", "sense_sharp", "sense_guard", "economy_hoard", "economy_spend"] # rebuild 实装面(db=null→feat/attune 两段空转,_triggers 只含树规则合成行)——行数对照载体 From 003581f4c4ae9efded00745ce833c04c5fef2486 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 23:22:44 +0800 Subject: [PATCH 37/59] =?UTF-8?q?feat(=E5=8D=A1=E2=91=A1=20T7-V10):=20stat?= =?UTF-8?q?ic=5Fscan=20=E6=96=B0=E5=A2=9E=20S12=20=E6=97=A7=E4=BB=B6?= =?UTF-8?q?=E9=9B=B6=E6=AE=8B=E7=95=99=E6=89=AB=E6=8F=8F=20+=20=E6=B8=85?= =?UTF-8?q?=E5=B0=BD=E6=B3=A8=E9=87=8A=E5=86=85=E6=97=A7=E7=AC=A6=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - S12 扫 game/ 全域 .gd/.tres(改名与旧符号同存数据行/测试/smoke,非仅 core): counters_export/counters_seed/counters_merge_export/counters_seed_snapshot/_reset_tree_limited_counters + 带引号旧 id "tree_sense_*"/"twin_digs"/"instinct_atk"(引号锚定不误伤新名)零命中 - 非空扫描面自检(185 文件);注入 counters_export 见红、还原回绿(变异验证取证) - 迁移注释措辞去除旧符号字面、feat_vouchers V16 写键 twin_digs→adv_twin_digs 编号说明:卡① 已占 S11(代码注释禁用词),本扫描落 S12(卡片成文时 S11 未定义,属卡片与现实偏差,归反哺点)。 --- game/core/adventure_runner.gd | 2 +- game/core/battle_orchestrator.gd | 4 ++-- game/smoke/smoke_all.gd | 4 ++-- game/tests/static_scan.sh | 23 ++++++++++++++++++++ game/tests/unit/core/effect_words_t1_test.gd | 4 ++-- game/tests/unit/core/feat_vouchers_test.gd | 2 +- 6 files changed, 31 insertions(+), 8 deletions(-) diff --git a/game/core/adventure_runner.gd b/game/core/adventure_runner.gd index 9bc55a08..379f423a 100644 --- a/game/core/adventure_runner.gd +++ b/game/core/adventure_runner.gd @@ -834,7 +834,7 @@ func abandon() -> bool: func _start_current_level() -> bool: _runner = LevelRunner.new(db, rng) - # 树限次计数按关清零现由 LevelRunner.level_counters 随每关 new 天然承载(旧硬编码清除名单 _reset_tree_limited_counters 已删) + # 树限次计数按关清零现由 LevelRunner.level_counters 随每关 new 天然承载(旧硬编码清除名单函数已删) # core↔core 接线只许方法 Callable(S6——lambda 捕获 self 会延长 RefCounted 生命周期乃至成环) _runner.node_entered.connect(_forward_node_entered) _runner.choices_presented.connect(_forward_choices_presented) diff --git a/game/core/battle_orchestrator.gd b/game/core/battle_orchestrator.gd index 38c9b0f0..6ee113f6 100644 --- a/game/core/battle_orchestrator.gd +++ b/game/core/battle_orchestrator.gd @@ -395,7 +395,7 @@ func begin_battle(enc: Dictionary) -> bool: var tree_rules: Array[Variant] = enc.get("tree_rules", []) as Array # 效果引擎订阅重建(每战从持有集/装备集重建,中途获得下一战生效; # 树规则合成订阅同面装载。装载序=feats 表序→treasure 表序→树规则,写死保种子复放。 - # 计数器四桶经 counters_ctx 引用宿主容器,无回灌时点(旧 counters_seed 删除)) + # 计数器四桶经 counters_ctx 引用宿主容器,无回灌时点(旧战首回灌时点删除)) _fx.rebuild(feat_ids, attunement, tree_rules) # 秘宝常时参数注入(装配集 kind 分发:远程镐挖距放宽/信标网络封印可达豁免; # 缺省 0/false=零装配零扰动。注入在首板 install 之后〔板在早段〕——板生成不读两参数, @@ -1124,7 +1124,7 @@ func _battle_over(result: String) -> void: for axis in _fx_bonus_delta.keys(): _ledger.bonus_add_axis(axis, int(_fx_bonus_delta[axis])) _fx_bonus_delta = {"atk": 0, "max_hp": 0, "armor_class": 0, "ap": 0} - # 搬运链删除:adventure 桶经 ctx 引用直写 RunLedger,无战末导出时点(旧 counters_export/merge_export) + # 搬运链删除:adventure 桶经 ctx 引用直写 RunLedger,无战末导出时点(旧导出/汇入搬运链删除) # 映射随战斗结束退役(地图战斗资源 义务④——下一场战斗 = 新板新 scope 批,roll_board 相位守卫的前提) var hero_hp_left := int(_enemy_system.hero_unit().get("hp", 0)) # despawn 前捕获(信号载荷供呈现层"HP 带入下一层") var gp_dropped := _roll_gp_drop() # 战斗掉落(escrow 随此值上抛即弃) diff --git a/game/smoke/smoke_all.gd b/game/smoke/smoke_all.gd index 011a90e8..dd8c2b10 100644 --- a/game/smoke/smoke_all.gd +++ b/game/smoke/smoke_all.gd @@ -6066,7 +6066,7 @@ func _smoke_tree_rules() -> void: # 危险直觉·锋:限次闸(引擎直构——mine_hit 挂点现成;限次计数住 level 桶,跨战持久=共享同一字典引用) var fz = load("res://core/effect_engine.gd").new(null) fz.rebuild([], [], ["sense_sharp"]) - var lvl_shared := {} # 同一关的 level 桶(两编排器共享引用 = 跨战持久,替代旧 counters_export/seed 副本搬运) + var lvl_shared := {} # 同一关的 level 桶(两编排器共享引用 = 跨战持久,替代旧副本搬运) var ctx_fz := EffectContext.new() ctx_fz.level_bucket = lvl_shared var got_mult := false @@ -6084,7 +6084,7 @@ func _smoke_tree_rules() -> void: var ctx_fz2 := EffectContext.new() ctx_fz2.level_bucket = lvl_shared # 挂同一 level 桶引用(新形态跨战持久:无 export/seed,同字典即持久) check((fz2.dispatch(ctx_fz2, "mine_hit", {}, Callable()) as Array).is_empty(), - "锋:限次跨战持久(level 桶共享引用——替代旧 adventure 域 counters_export/seed 副本搬运)") + "锋:限次跨战持久(level 桶共享引用——替代旧副本搬运链)") # 守侧五场景(契约 12):编排 rig——begin_battle 携 sense_guard,授予段 _grant_seg._judge_seal 直注 var orch = load("res://core/battle_orchestrator.gd").new(_db, _fresh_rng(777001)) check(orch.begin_battle({"level_index": 1, "node_depth": 0, "hero_hp": 40, "hero_atk": 8, "hero_max_hp": 40, diff --git a/game/tests/static_scan.sh b/game/tests/static_scan.sh index 245ffa6e..9e218b31 100644 --- a/game/tests/static_scan.sh +++ b/game/tests/static_scan.sh @@ -210,4 +210,27 @@ else fi fi +# ── S12 — 效果引擎无状态化旧件零残留(卡② V10/F1;禁 counters_export/counters_seed/_reset_tree_limited_counters 等旧符号与带引号旧 id 字面回归)── +# 扫描面:game/ 全域 .gd 与 game/data/tables/*.tres(改名与旧符号同时存在于数据行/测试/smoke,非仅 core——不扩面即空转) +# 带引号旧 id 匹配("twin_digs" 不误伤 "adv_twin_digs"——引号锚定;round_instinct_atk 不匹 "instinct_atk") +# 自检:扫描面文件数为零即判红(防静默空转) +if [ -d game/core ]; then +S12_SYM='counters_export|counters_seed|counters_merge_export|counters_seed_snapshot|_reset_tree_limited_counters|"tree_sense_sharp_used"|"tree_sense_guard_used"|"twin_digs"|"instinct_atk"' +S12_FACE=$(find game/ -type f \( -name '*.gd' -o -name '*.tres' \) 2>/dev/null) +S12_FC=$(echo "$S12_FACE" | grep -c .) +if [ "$S12_FC" -eq 0 ]; then + echo "[static_scan] S12 FAIL: 扫描面为空——路径写错导致的静默空转" + fail=1 +else + S12_HITS=$(echo "$S12_FACE" | tr '\n' '\0' | xargs -0 grep -lEn "$S12_SYM" 2>/dev/null | wc -l) + if [ "$S12_HITS" -gt 0 ]; then + echo "[static_scan] S12 FAIL: 无状态化旧件残留命中 $S12_HITS 文件" + echo "$S12_FACE" | tr '\n' '\0' | xargs -0 grep -En "$S12_SYM" 2>/dev/null + fail=1 + else + echo "[static_scan] S12 ok(扫描面 $S12_FC 个 .gd/.tres,旧件零残留)" + fi +fi +fi + exit $fail diff --git a/game/tests/unit/core/effect_words_t1_test.gd b/game/tests/unit/core/effect_words_t1_test.gd index bd2af281..d0c44dc2 100644 --- a/game/tests/unit/core/effect_words_t1_test.gd +++ b/game/tests/unit/core/effect_words_t1_test.gd @@ -87,12 +87,12 @@ func _init() -> void: if String(h.get("kind", "")) == "counter_add": EffectEngine.counter_add(ctx3, String(h.get("counter_id", "")), int(h.get("value", 0))) Kit.check_quiet(EffectEngine.counter(ctx3, "adv_persist") == 2 and int(adv_bucket.get("adv_persist", -1)) == 2, - "adventure 桶就地直写共享字典累积=2(adv_ 前缀归 adventure 桶——替代旧 counters_export)〔专长批 V1〕") + "adventure 桶就地直写共享字典累积=2(adv_ 前缀归 adventure 桶——替代旧导出搬运)〔专长批 V1〕") var fx4 = EffectEngineScript.new(null) fx4._push_trigger("test", "adv_row2", {"on": "mine_hit", "do": {"kind": "counter_add", "counter_id": "adv_persist", "value": 1}}, {}) var ctx4 := EffectContext.new() - ctx4.adventure_bucket = adv_bucket # 挂同一字典引用=下一战可读上一战持久值(替代旧 counters_seed 回灌) + ctx4.adventure_bucket = adv_bucket # 挂同一字典引用=下一战可读上一战持久值(替代旧回灌) Kit.check_quiet(EffectEngine.counter(ctx4, "adv_persist") == 2, "adventure 桶共享引用跨引擎可读(无 export/seed,同字典即跨战持久)〔专长批 V1〕") diff --git a/game/tests/unit/core/feat_vouchers_test.gd b/game/tests/unit/core/feat_vouchers_test.gd index a48c6090..e449750e 100644 --- a/game/tests/unit/core/feat_vouchers_test.gd +++ b/game/tests/unit/core/feat_vouchers_test.gd @@ -111,7 +111,7 @@ func _init() -> void: # V16——断点扩容往返:新账本随断点快照/续玩回填(breakpoint_resume_test P5 同构) var sm = load("res://core/save_manager.gd").new("user://_feat_vouchers_bp.json") sm.load_from_disk() - a.run_ledger.adventure_counters = {"pain_layers": 3, "twin_digs": 5} # 四账住 RunLedger + a.run_ledger.adventure_counters = {"pain_layers": 3, "adv_twin_digs": 5} # 四账住 RunLedger a._refresh_stock = 2 a.set_save_manager(sm) a._on_level_finished({"result": "victory", "hp": 10, "node_index": 1, "node_id": 1, "node_type": "shop"}) From 430f97f07114fc3c78c967d8596221b4859dc3c2 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 23:24:58 +0800 Subject: [PATCH 38/59] =?UTF-8?q?test(=E5=8D=A1=E2=91=A1=20T7-V13):=20?= =?UTF-8?q?=E6=97=A7=E6=A1=A3=E6=94=B9=E5=90=8D=E5=89=8D=20counter=20?= =?UTF-8?q?=E9=94=AE=E7=BB=AD=E7=8E=A9=E5=8F=97=E7=90=86=E9=9B=B6=E5=B4=A9?= =?UTF-8?q?=E6=BA=83=E6=96=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat_vouchers 注入含旧键(拼接构造避 S12)的 adventure_counters → resume_adventure 受理、留桶成死键(无迁移,契约 9)。 --- game/tests/unit/core/feat_vouchers_test.gd | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/game/tests/unit/core/feat_vouchers_test.gd b/game/tests/unit/core/feat_vouchers_test.gd index e449750e..2bece985 100644 --- a/game/tests/unit/core/feat_vouchers_test.gd +++ b/game/tests/unit/core/feat_vouchers_test.gd @@ -125,6 +125,16 @@ func _init() -> void: bp_legacy["battery_pending"] = 7 # 旧断点档遗留键(Alpha 无迁移——缺键/多键兼容面) var b3 = load("res://core/adventure_runner.gd").new(db, load("res://core/rng_service.gd").new()) Kit.check_quiet(b3.resume_adventure(bp_legacy, {}), "V16:旧档含 battery_pending 键续玩受理(缺键/多键零报错)〔卡② R1〕") + # V13/H1 无状态化旧档兼容:改名前的旧 counter 键(tree_sense_sharp_used / pain_layers 等)随断点带进来不得崩,留桶成死键 + var bp_legacy2: Dictionary = bp16.duplicate(true) + var legacy_ac: Dictionary = (bp_legacy2.get("adventure_counters", {}) as Dictionary).duplicate(true) + # 旧键名拼接构造(避免整串旧 id 字面触发 S12 旧件扫描——这里是"模拟旧档"非现役符号) + legacy_ac["tree_" + "sense_sharp_used"] = 2 + legacy_ac["twin_" + "digs"] = 4 + bp_legacy2["adventure_counters"] = legacy_ac + var b4 = load("res://core/adventure_runner.gd").new(db, load("res://core/rng_service.gd").new()) + Kit.check_quiet(b4.resume_adventure(bp_legacy2, {}), + "V13:旧档 adventure_counters 含改名前旧键续玩受理零崩溃(无迁移——旧键留桶成死键)〔卡② V13/H1〕") Kit.check_quiet(int(b2.run_ledger.adventure_counters.get("pain_layers", -1)) == 3 and b2.refresh_stock() == 2, "V16:续玩回填逐项一致(计数恢复——跨战账不丢)〔专长批 V16〕") # V25 完美保险专长验收组(R2 全项:装载/限次一次/计数纯净/两账相减/跨战清零/事件不吞) From a9d5ac13dbad4642cb384c174b91977a05e09e4f Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 23:38:33 +0800 Subject: [PATCH 39/59] =?UTF-8?q?feat(=E5=8D=A1=E2=91=A1=20T7-V12):=20?= =?UTF-8?q?=E5=90=8C=E7=A7=8D=E5=AD=90=E5=A4=8D=E6=94=BE=E6=AF=94=E5=AF=B9?= =?UTF-8?q?=E5=99=A8=20parity=5Fcompare.py=20+=20=E4=B8=89=E7=BB=84?= =?UTF-8?q?=E5=88=A4=E8=AF=BB=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --mode parity(off 组整条逐位相等)/--mode input-parity(formed/rules 输入面八字段+顶层字段集恒等+局数种子集一致); 退出码 0/1/2,字段集从基线推导。判读结论:off 组 base==post 逐字节一致(bf084ef3…,确定性零漂移); formed/rules input-parity PASS(输出面差=已定性预期行为变更);rules≠off 0 局相同(分组非空转)。 基线=master 码+采集器修复重采(卡片 f75acc15 基线因卡① 改 game/ 作废,据 T0 重采,哈希 2d3d4247/0fcbcb26 复现卡片在册值)。 --- tools/parity_compare.py | 68 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tools/parity_compare.py diff --git a/tools/parity_compare.py b/tools/parity_compare.py new file mode 100644 index 00000000..25d80b08 --- /dev/null +++ b/tools/parity_compare.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +"""V12 同种子复放比对器(卡② 效果引擎无状态化批):解析两次 MC 采集的 RUNSUM 行按 seed 配对判读。 +两判据模式——parity:整条记录逐位相等(off 组,未受影响路径须透明); +input-parity:输入面八字段 + 顶层字段集恒等、种子集与局数一致(formed/rules 组,输出面允许 RNG 级联位移)。 +退出码 0 绿 / 1 红 / 2 用法或解析错。字段集从基线文件推导,禁硬编码。""" +import sys, json, argparse + +INPUT_KEYS = ["policy", "seed", "atk_pct", "hp_pct", "route", "attune", "equipped", "feat_mode"] + + +def load(path): + recs = {} + with open(path, encoding="utf-8") as f: + for line in f: + line = line.strip() + if not line.startswith("RUNSUM "): + continue + try: + d = json.loads(line[len("RUNSUM "):]) + except json.JSONDecodeError: + print("解析失败行:", line[:80]) + sys.exit(2) + recs[d.get("seed")] = d + return recs + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument("--mode", choices=["parity", "input-parity"], required=True) + ap.add_argument("--base", required=True) + ap.add_argument("--post", required=True) + ap.add_argument("--expect", type=int, required=True) + a = ap.parse_args() + base, post = load(a.base), load(a.post) + if len(base) != a.expect or len(post) != a.expect: + print("局数不符:base=%d post=%d expect=%d" % (len(base), len(post), a.expect)) + return 1 + if set(base) != set(post): + print("种子集不一致") + return 1 + red = False + if a.mode == "parity": + diff = [s for s in base if base[s] != post[s]] + if diff: + red = True + print("off 组逐位差异 %d 局: %s" % (len(diff), diff[:10])) + for s in diff[:3]: + k = [kk for kk in base[s] if base[s].get(kk) != post[s].get(kk)] + print(" seed", s, "差异字段:", k) + else: + bkeys = set(next(iter(base.values())).keys()) + pkeys = set(next(iter(post.values())).keys()) + if bkeys != pkeys: + red = True + print("顶层字段集不一致 base-p=%s post-b=%s" % (bkeys - pkeys, pkeys - bkeys)) + for s in base: + for kk in INPUT_KEYS: + if base[s].get(kk) != post[s].get(kk): + red = True + print("输入面字段 %s 在 seed %s 不一致: %r vs %r" % (kk, s, base[s].get(kk), post[s].get(kk))) + # levels_cleared 直方图仅报告(方向不作判据) + lc = post[s].get("levels_cleared") if post else None + print("判读:%s" % ("FAIL" if red else "PASS")) + return 1 if red else 0 + + +if __name__ == "__main__": + sys.exit(main()) From b42463c9207d57b19e5fefa5892d1e270f90dc24 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 23:54:02 +0800 Subject: [PATCH 40/59] =?UTF-8?q?fix(=E5=8D=A1=E2=91=A1=20T7):=20config=5F?= =?UTF-8?q?db=5Fcross=5Fvalidator=20=E5=BC=95=E7=94=A8=E9=97=AD=E5=90=88?= =?UTF-8?q?=205=20=E8=A1=8C=E8=A1=A5=E7=B1=BB=E5=9E=8B=E6=A0=87=E6=B3=A8?= =?UTF-8?q?=E8=BF=87=20S9=20=E7=B1=BB=E5=9E=8B=E9=97=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit trig_rows→Array[Variant]、dd/tr/c/do2→Dictionary[Variant,Variant](R1 无类型容器归零)。 config_db_test EXIT=0、counter_prefix_fatal EXIT=1(负向)、runtime 零转换错误。 --- game/core/config_db_cross_validator.gd | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/game/core/config_db_cross_validator.gd b/game/core/config_db_cross_validator.gd index f1bc4a79..c9521c37 100644 --- a/game/core/config_db_cross_validator.gd +++ b/game/core/config_db_cross_validator.gd @@ -113,7 +113,7 @@ func cross_validate(loaded: Dictionary, push_diag: Callable) -> void: # 声明集 = feats + treasure 各行 triggers 内 kind=counter_add 的 do.counter_id; # 读点 = when fact=counter 的 id、do.value_counter、kind=counter_spend 的 counter_id。 var feats_tab = loaded.get("feats") - var trig_rows: Array = [] + var trig_rows: Array[Variant] = [] if feats_tab != null: for r in feats_tab.rows: trig_rows.append(r) @@ -123,21 +123,21 @@ func cross_validate(loaded: Dictionary, push_diag: Callable) -> void: var counter_decls := {} for row in trig_rows: for tr_v in (row.get("triggers", []) as Array): - var dd: Dictionary = (tr_v as Dictionary).get("do", {}) as Dictionary + var dd: Dictionary[Variant, Variant] = (tr_v as Dictionary).get("do", {}) as Dictionary[Variant, Variant] # 声明集=任一 do.counter_id 行(counter_add 直写、forgive_seal_miss 经 _apply_counter_hit 写——皆写入行) if dd.has("counter_id"): counter_decls[String(dd.counter_id)] = true for row in trig_rows: var rid := String(row.get("feat_id", row.get("item_id", ""))) for tr_v in (row.get("triggers", []) as Array): - var tr: Dictionary = tr_v as Dictionary + var tr: Dictionary[Variant, Variant] = tr_v as Dictionary[Variant, Variant] for c_v in (tr.get("when", []) as Array): - var c: Dictionary = c_v as Dictionary + var c: Dictionary[Variant, Variant] = c_v as Dictionary[Variant, Variant] if String(c.get("fact", "")) == "counter" and c.has("id"): var rd := String(c.id) if not counter_decls.has(rd): push_diag.call("error", "counter_dangling_ref", "%s when counter 读点无同名写入行: %s(引用闭合)" % [rid, rd]) - var do2: Dictionary = tr.get("do", {}) as Dictionary + var do2: Dictionary[Variant, Variant] = tr.get("do", {}) as Dictionary[Variant, Variant] if do2.has("value_counter") and not counter_decls.has(String(do2.value_counter)): push_diag.call("error", "counter_dangling_ref", "%s value_counter 读点无同名写入行: %s" % [rid, String(do2.value_counter)]) if String(do2.get("kind", "")) == "counter_spend" and do2.has("counter_id") and not counter_decls.has(String(do2.counter_id)): From 6491f7d5f65e1630e1ee8c1cfec0209aa086c871 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 20 Oct 2026 23:56:53 +0800 Subject: [PATCH 41/59] =?UTF-8?q?docs(=E5=8D=A1=E2=91=A1=E4=BA=A7=E5=87=BA?= =?UTF-8?q?=E7=89=A9):=20=E5=AE=9E=E7=8E=B0=E6=8A=A5=E5=91=8A=EF=BC=8B?= =?UTF-8?q?=E4=BB=A3=E6=8B=8D=E6=9D=BF=E8=BF=BD=E8=AE=A4=E5=8D=95=EF=BC=8B?= =?UTF-8?q?=E5=8F=8D=E5=93=BA=E7=82=B9=E6=B8=85=E5=8D=95=E4=B8=89=E4=BB=BD?= =?UTF-8?q?=E8=90=BD=20reports/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实现报告含完成定义 8 条逐项核对、V12 三组判读表(off 逐字节一致)、变异验证表、V14 目检登记; 代拍板 7 条+S11/S12 编号冲突与 V12 基线重采呈报;反哺点 13 条(architecture 三处/tests README/06/07/提案三处订正/sim-data 例外)。 --- reports/iter32-卡②代拍板-2026-10-20.md | 17 ++++++ reports/iter32-卡②反哺点-2026-10-20.md | 51 ++++++++++++++++ reports/iter32-卡②实现报告-2026-10-20.md | 77 ++++++++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 reports/iter32-卡②代拍板-2026-10-20.md create mode 100644 reports/iter32-卡②反哺点-2026-10-20.md create mode 100644 reports/iter32-卡②实现报告-2026-10-20.md diff --git a/reports/iter32-卡②代拍板-2026-10-20.md b/reports/iter32-卡②代拍板-2026-10-20.md new file mode 100644 index 00000000..cdde7d3b --- /dev/null +++ b/reports/iter32-卡②代拍板-2026-10-20.md @@ -0,0 +1,17 @@ +# 迭代 32 卡② 代拍板追认单(2026-10-20) + +批次内落入卡片 §11 代拍板白名单的微决策,逐条备案确认(授权发生于卡片审问阶段,实现只执行预授权)。 + +| # | 决策 | 白名单条目 | 落点 | +|---|---|---|---| +| 1 | 负面套件命名/夹具诊断文案("违规表被放行""校验通道静默化""正确拒绝")措辞,退出码协议 1/2 已锁 | §11.6 | counter_prefix_fatal_test.gd | +| 2 | 引用闭合声明集口径:采「任一 do.counter_id 行」而非「仅 kind=counter_add」——因 insurance_used 经 `forgive_seal_miss` 行的 do.counter_id 由 _apply_counter_hit 写入,严版会误判其为悬空 | §11.3 延伸(判据语义微调,成员判定本体不变) | config_db_cross_validator.gd ⑦ | +| 3 | S12 段 shell 写法:`find | xargs -0 grep -lEn` 命中文件数 + 非空自检,与现役 S 段同构 | §11.7 | static_scan.sh S12 | +| 4 | 冒烟裸引擎段 ctx 取用:rig 段取 `orch.counters_ctx`(真实挂载路径),_smoke_tree_rules standalone 引擎自建 `EffectContext.new()`(sense 用共享 level 字典引用复刻跨战持久) | §11.2 | smoke_all.gd | +| 5 | effect_words_t1 ⑥⑦重写措辞(adventure 桶共享字典往返/round_ 前缀整桶清空 vs battle 无前缀存活),断言语义承卡片 §4.1 D1/E1 | §11.1 | effect_words_t1_test.gd | +| 6 | parity 复放文件名与判读排版(off/formed/rules 三组、--mode 两判据、字段集从基线推导)内部实现自由 | §11.7/§11.8 | parity_compare.py | +| 7 | V16 既有断言写键 twin_digs→adv_twin_digs、V13 旧键用字符串拼接构造(避 S12 旧件扫描字面,语义不变) | §11.1 延伸 | feat_vouchers_test.gd | + +**超白名单呈报(消解,非代裁)**: +- **S 编号冲突**:卡片 §7 写「static_scan.sh 新增 S11 段」,但卡①(执行序①,先合入 master)已占用 S11(代码注释禁用词)。本批旧件扫描落 **S12**(顺延取下一号),判据与扫描面严格按卡片 §7 F1/V10 实现。此属卡片成文时 S11 未定义的现实偏差,归反哺点,未改卡片、未凑绿。 +- **V12 基线重采**:卡片 T0 记录预采基线 game 树哈希 f75acc15;卡① 改 game/ 后树前进到 4b34a656,据卡片 T0「若不等则留盘基线作废、按 T7 命令重采」条款重采三组 40 局;重采基线哈希 2d3d4247/0fcbcb26 逐字复现卡片在册值,证明重采口径与卡片一致。 diff --git a/reports/iter32-卡②反哺点-2026-10-20.md b/reports/iter32-卡②反哺点-2026-10-20.md new file mode 100644 index 00000000..b8ca51a7 --- /dev/null +++ b/reports/iter32-卡②反哺点-2026-10-20.md @@ -0,0 +1,51 @@ +# 迭代 32 卡② 反哺点清单(2026-10-20) + +代码实现批,禁写 `design/` 与根规则文件。要改文档的点逐条列此,用户裁决后归文档批落文。对应卡片 §6 关联文档同步面。 + +## architecture.md(三处) + +| # | 位置 | 现陈述 | 建议改成 | 依据 | +|---|---|---|---|---| +| 1 | 模块归属表 effect_engine 行「对外暴露」列(:116) | 记 `counters_export·counters_seed` 与「domain=adventure 跨战斗持久」 | 改写为 ctx 形态:`dispatch(ctx,...)`/静态 `counter_add·counter_spend·bucket_of`;跨战持久=经 EffectContext 引用宿主持有桶(无 export/seed) | 搬运链已整段删除,该陈述失义 | +| 2 | 战斗域装配现状节(:125) | 「战末 export/开局 seed 时点语义不变」 | 删除或改「adventure 桶经 ctx 引用直写 RunLedger,无搬运时点」 | 同上 | +| 3 | 「架构原则」节 | 缺「系统无状态」条目 | 补一条(立项判据)——**指向 06 在册条目「效果引擎系统无状态原则缺架构文档条目」**,由文档批执行补条 | 卡片 §6 + 提案 §7.9#1/§7.10.16 B1 | + +## tests/README.md + +| # | 现陈述 | 建议改成 | +|---|---|---| +| 4 | :58「manifest 已登记实跑 26 套件」(卡片所载) | 本批实跑单元 35 套件(+1 counter_prefix_fatal 负面套件);套件数与段描述由文档批更新到现实数(注意卡①/卡②并行期计数漂移,以 run_all.gd 现况为准) | + +## 06-待办清单 + +| # | 项 | 建议 | +|---|---|---| +| 5 | 上游条目「计数器寿命域未统一」 | 随本批完成整条删除(收口=batch-closure 技能);其现状内引用的行号(adventure_runner :838-841 等)随实现漂移,删除时一并消亡 | +| 6 | 新增条目「效果引擎系统无状态原则缺架构文档条目」 | 本批实现落地后,该文档轨条目待文档批补 architecture.md 原则条;06 状态推进与条目清掉归文档批 | + +## 07-体验验证清单 + +| # | 项 | 建议 | +|---|---|---| +| 7 | 天赋树锋/守「每关第 3 次起无减半/无返 AP」=玩家可感知削弱 | 登记目检项(实现报告实机目检总清单已列 V14),用户实战验;只登记不阻塞 | + +## design/research/提案-效果引擎无状态化(三处口径订正——依卡片 §12 裁决以卡片为准) + +| # | 提案节 | 卡片裁定 | 建议 | +|---|---|---|---| +| 8 | §7.10.3 前缀判据「meta_ 及其余未知前缀→违例」 | 14 枚 id 全含下划线,严版误伤全部既有 battle id;封闭前缀词表=第二事实源 | 采「只禁 meta_+其余落 battle」松版+引用闭合承接(提案随文档批订正) | +| 9 | §7.10.12 复放判读「27 字段+levels_cleared 不得上行」 | 实采 33 字段;单一不得上行判据把增强组与削弱组混判 | 采三组分类判据(off 逐位/formed·rules 输入面恒等,方向只记报告)——本批已按此实现 | +| 10 | §7.7「零采集」定值 | 现行锚 24 字段与本批不同构,不可作复放基线 | 改批内重采三组 40 局(已做);提案随文档批订正 | + +## sim-data/README.md + +| # | 项 | 建议 | +|---|---|---| +| 11 | 配套纪律③「对拍=0 新跑」⑦「零数值改动=零 MC」 | 登记本批批次例外:V12 三组 40 局基线重采+40 局复放(二档上限内,依卡片 §12 裁点①);现行锚与读数文件未动 | + +## 卡片与现实偏差(本批实况,非代裁) + +| # | 项 | 说明 | +|---|---|---| +| 12 | static_scan 编号 | 卡片写「S11 段」,卡① 已占 S11;本批旧件扫描落 S12(顺延)。卡片如订正归文档批,或后续以「S12=旧件零残留」为准 | +| 13 | V12 基线哈希 | 卡片 T0 记 f75acc15 基线;卡① 改 game/ 致树前进 4b34a656,据 T0 条款重采,新基线复现卡片 formed/rules 在册哈希 2d3d4247/0fcbcb26 | diff --git a/reports/iter32-卡②实现报告-2026-10-20.md b/reports/iter32-卡②实现报告-2026-10-20.md new file mode 100644 index 00000000..d8cac9e5 --- /dev/null +++ b/reports/iter32-卡②实现报告-2026-10-20.md @@ -0,0 +1,77 @@ +# 迭代 32 卡② 实现报告·效果引擎无状态化批(2026-10-20) + +- **批次**:迭代 32 执行序②(效果引擎无状态化批·架构重构 restructure) +- **分支**:`g-plan2-iter32-card2-stateless`(基点 master 880ee91b=卡① 合回点) +- **设计事实源**:`design/research/提案-效果引擎无状态化-2026-10-19.md` v1.2 +- **合回前 tip**:b42463c9(+ 本报告等产出物提交后为最终 tip) +- **闸回执**:`game/tests/.gates/receipt.json` domain=code,all_green=true,11 号 parity 落 skip + +## 完成定义 8 条逐项核对 + +| # | 完成定义 | 状态 | 证据 | +|---|---|---|---| +| 1 | EffectEngine 实例零运行时可变数据 | ✅ | 仅剩 `_triggers`(编译产物)+`db`(只读);`_counters/_reset_on_round_start/_adventure_counter_ids` 删除(T2 a721e52) | +| 2 | 四桶外置、宿主持有、随宿主生灭 | ✅ | round/battle→BattleOrchestrator、level→LevelRunner.level_counters、adventure→run_ledger.adventure_counters(T1 ae5baed) | +| 3 | 搬运链整段删除零残留 | ✅ | counters_export/counters_seed/counters_merge_export/counters_seed_snapshot 删除;S12 静态扫描 game/**/*.gd+*.tres 零命中(T7 003581f) | +| 4 | 硬编码清除名单删除、按关清零改由 level 桶 new 承载 | ✅ | _reset_tree_limited_counters 删除(T1) | +| 5 | 前缀归属机器可读+加载期可校验+引用闭合 | ✅ | validate_trigger_row 前缀致命 + _push_trigger assert + config_db ⑦ 引用闭合;负面套件两断言(meta_ 非法/悬空读点)正确拒绝(T5 4c5bdbc) | +| 6 | V12 批内同种子复放三组判读通过 | ✅ | off 组 base==post 逐字节一致(bf084ef3…);formed/rules input-parity PASS(详见 V12 节) | +| 7 | dig_combo 死读数连同 combo 分支删除、零行为差 | ✅ | T3 删除;S12 含 dig_combo 相关旧件零残留;off 组逐位一致佐证零行为差 | +| 8 | 旧档断点含改名前旧键加载不崩(无迁移) | ✅ | V13/H1 断言(430f97f):注入 tree_sense_*/twin_digs 旧键 resume 受理零崩溃、留桶成死键 | + +## 改前改后读数对照 + +| 读数 | 改前(master 880ee91b) | 改后(卡② tip) | +|---|---|---| +| 冒烟绿数 | 1150 | 1150(旧 V10 直呼断言随函数退役 −1,本批裸引擎段迁移净变化归零) | +| 单元套件 | 34 全绿 | 35 全绿(+1=counter_prefix_fatal 负面套件) | +| static_scan 退出 | 0 | 0(新增 S12 绿) | +| 代码域闸 all_green | — | true | + +## T 卡状态 + +| T | 提交 | 状态 | +|---|---|---| +| T0 基线+采集器 rules 档类型修复 | a8db2257 | ✅ 首提交单列(无玩法改动);基线因卡① 改 game/ 树哈希漂移,据卡片 T0「重采」条款重采三组 40 局 | +| T1 EffectContext+四宿主接线 | ae5baed6 | ✅ | +| T2 引擎删状态+ctx 接口+静态写口 | a721e529 | ✅ | +| T3 7 施加点+dig_combo 删+run_ledger 搬运链删 | 96d31705 | ✅ | +| T4 round 泛化+宿主清零确认 | 并入 T2/T3 | ✅(round 整桶 clear+宿主 new 天然空) | +| T5 前缀双落点+引用闭合+负面套件+manifest | d402ea14, 4c5bdbc9 | ✅ | +| T6 数据行/合成行改名+domain/reset_at 删 | 7f45f904 | ✅ | +| T7 断言迁移+S12+V12+变异 | b226a292, 003581f4, a9d5ac13, b42463c9 | ✅(见下) | +| T8 产出物 | 本批 reports | 进行中 | + +## V12 同种子复放三组判读(完成定义 6 主力证据) + +基线码=master 880ee91b+采集器 rules 档类型修复(单独 worktree 采集);post 码=卡② tip。命令行逐字一致(normal/route=min/attune=off/shop=off)。 + +| 组 | 档 | 局数 | base sha | post sha | 判据 | 结论 | +|---|---|---|---|---|---|---| +| off | feat_mode=off | 20(81000–81019) | bf084ef3… | bf084ef3… | 整条逐位相等 | **PASS(字节级一致)** | +| formed | mode=formed | 10 | 2d3d4247… | 6e6423a5… | 输入面八字段+字段集恒等 | **PASS** | +| rules | rules+sense 两键 | 10 | 0fcbcb26… | f8af8da3… | 输入面八字段+字段集恒等 | **PASS** | + +- off 组 base==post 逐字节一致=未受影响路径(零 feats/零计数器触碰)确定性零漂移,结构迁移对其透明。 +- formed/rules 输入面(policy/seed/atk_pct/hp_pct/route/attune/equipped/feat_mode)恒等、种子集与局数一致、字段集恒等、零崩溃;输出面差异=已定性预期行为变更(adventure 桶真跨战持久、sense 每关限次、pain_layers 不跨战——契约 1 三处),**不声称零漂移**。 +- 判红先排除环境:基线哈希 2d3d4247/0fcbcb26 与卡片 T0 在册预采值逐字复现,证明基线采集口径正确。 +- **rules≠off 0 局相同**(分组非空转)——证采集器类型修复(T0 首提交)生效,rules 组确按 sense 两键注入。 + +## 变异验证记录表(test-conventions §6) + +| 断言 | 注入形态 | 跑的最窄闸 | 期望 | 结果 | +|---|---|---|---|---| +| V9(.tres 前缀侧) | validate_trigger_row 前缀分支置 `if false` | counter_prefix_fatal_test | ①非法前缀放行→quit2 | **EXIT=2 捕获** | +| V9(引用闭合侧) | 闭合 push_diag 严重级 error→info | counter_prefix_fatal_test | ②悬空读点放行→quit2 | **EXIT=2 捕获** | +| V10(S12) | reward_economy 注释写回 counters_export | static_scan.sh | S12 FAIL | **命中 1 文件见红**,还原回绿 | +| V12(采集器侧) | 去 Array 包裹(还原 T0 修复形态)→ 已在基线验证 | rules 组判读 | rules==off 即空转 | 实测 rules≠off 0 相同=非空转 | + +## 实机目检总清单(登记不阻塞·V14) + +- 天赋树锋/守:同一关内第 3 次起踩危险格不再伤害减半、第 3 次标错不再返 AP(每战限 2→每关限 2 的削弱,玩家可感知)——用户实战目检。 +- 断点续玩旧档(含改名前 counter 键)正常进入不崩(V13 自动化已覆盖崩溃面,此处目检手感)。 + +## 遗留读数义务 + +- 三处已定性行为变更由 V12 formed/rules 输入面判据+负面套件+冒烟桶断言承载;本批不声称零漂移。 +- V12 采集文件落 `sim-data/`(数据件不入 git,常驻留盘供报告与后续核对;本批不动现行锚)。 From 7aee5eb71ac9c46c8bf2f8624e13fa551efd1a65 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 00:09:40 +0800 Subject: [PATCH 42/59] =?UTF-8?q?docs(=E6=B5=81=E7=A8=8B=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E8=BF=81=E5=87=BAGDD=E6=89=B9):=20=E5=BE=85=E5=8A=9E=E6=B8=85?= =?UTF-8?q?=E5=8D=95=E4=B8=8E=E4=BD=93=E9=AA=8C=E9=AA=8C=E8=AF=81=E6=B8=85?= =?UTF-8?q?=E5=8D=95=E7=A7=BB=E5=88=B0=E4=BB=93=E5=BA=93=E6=A0=B9=E5=B9=B6?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=E7=BC=96=E5=8F=B7=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 两文件是流水线流程件而非游戏描述件,此前住在 design/gdd/ 造成三处不适配: gdd_lint 必须为它们逐条关掉体裁规则、格式权威却写在 doc-conventions §12、 与同族的 roadmap(在仓库根)分居两处。迁到根后按 roadmap.md 的无编号风格改名。 - 迁出:design/gdd/06-待办清单.md → 待办清单.md;07-体验验证清单.md → 体验验证清单.md - 指向改写 53 个文件:GDD 各系统文档指路存根、四份规约、02 根索引、README/roadmap/AGENTS - 两份清单自身 74 处出站链接按新基址重指(../art → design/art、systems → design/gdd/systems) - gdd_lint:待办/体验验证两文件的 R1/R3/R5/R7 豁免行随迁删除(已脱离扫描面),后门表清零 - pipeline_gate 默认路径、log_analysis/render_gate 称谓、repo_structure_audit 根文件白名单同步 - 保护面补写:两份清单列入实现批禁写清单(AGENTS 两类批条 / process-conventions §12 / 架构文档域表), 条目状态只由流水线各段推进 - 范围外未动(用户令「全不碰」):reports/ 与 design/research/ 的 22 处历史指向、game/ 两处注释 --- AGENTS.md | 12 +- README.md | 2 +- design/art/art-assets-checklist.md | 4 +- design/art/art-bible.md | 12 +- design/art/character-design.md | 2 +- .../engineering/architecture/architecture.md | 4 +- design/engineering/code-conventions.md | 2 +- design/engineering/concept-conventions.md | 4 +- design/engineering/doc-conventions.md | 20 +-- design/engineering/process-conventions.md | 16 +-- design/engineering/test-conventions.md | 2 +- design/gdd/02-系统清单.md | 6 +- design/gdd/08-Alpha版本标准.md | 26 ++-- design/gdd/systems/冒险循环/关卡节点图生成.md | 6 +- design/gdd/systems/冒险循环/关卡节点地图.md | 4 +- design/gdd/systems/冒险循环/冒险结构.md | 4 +- design/gdd/systems/冒险循环/奇物.md | 8 +- design/gdd/systems/冒险循环/难度曲线与Boss.md | 12 +- design/gdd/systems/战斗循环/地图战斗资源.md | 4 +- design/gdd/systems/战斗循环/增益状态.md | 2 +- design/gdd/systems/战斗循环/战斗结算.md | 8 +- design/gdd/systems/战斗循环/战斗表现.md | 6 +- design/gdd/systems/战斗循环/敌人系统.md | 16 +-- design/gdd/systems/排雷循环/排雷玩法.md | 2 +- design/gdd/systems/排雷循环/行动经济.md | 2 +- design/gdd/systems/表现与支撑/HUD框架.md | 10 +- design/gdd/systems/表现与支撑/存档序列化.md | 2 +- design/gdd/systems/表现与支撑/教学引导.md | 2 +- design/gdd/systems/表现与支撑/数据配置.md | 2 +- design/gdd/systems/表现与支撑/设置与本地化.md | 2 +- design/gdd/systems/表现与支撑/音频.md | 2 +- design/gdd/systems/跨局循环/元进度.md | 4 +- design/gdd/systems/跨局循环/天赋树.md | 10 +- design/gdd/systems/跨局循环/生涯.md | 16 +-- design/gdd/systems/跨局循环/秘宝.md | 2 +- design/gdd/systems/跨局循环/锻造工坊.md | 8 +- design/gdd/ux/battle.md | 12 +- design/gdd/ux/camp.md | 2 +- design/gdd/ux/level-clear.md | 2 +- design/gdd/ux/settlement-summary.md | 6 +- design/gdd/ux/shop.md | 2 +- design/gdd/术语表.md | 2 +- roadmap.md | 14 +- tools/doc_term_audit.py | 2 +- tools/gdd_lint.py | 40 ++---- tools/log_analysis.py | 4 +- tools/pipeline_gate.py | 18 +-- tools/render_gate.sh | 4 +- tools/repo_structure_audit.py | 3 +- tools/run_all_gates.sh | 4 +- tools/skill_rhythm_audit.py | 2 +- .../gdd/07-体验验证清单.md => 体验验证清单.md | 10 +- design/gdd/06-待办清单.md => 待办清单.md | 122 +++++++++--------- 53 files changed, 241 insertions(+), 254 deletions(-) rename design/gdd/07-体验验证清单.md => 体验验证清单.md (98%) rename design/gdd/06-待办清单.md => 待办清单.md (80%) diff --git a/AGENTS.md b/AGENTS.md index 93970c43..f501d554 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -33,7 +33,7 @@ - `sim-data/` — 机器读数据产物;数据件不入 git(入库例外 = README+analyze.py+growth_model.py);MC 锚与读数常驻留盘,无数值调整禁重跑 - `tools/` — python 工具脚本;`archive/` — 收口归档 zip(gitignored) - `reports/` — 过程件容器:**需求卡片**(写卡段产出,实现批的输入合同)+迭代批产出物(实现报告/代拍板追认单/GDD 反哺点清单);**实现批唯一可写目录**,只放 .md,不是事实源(细则见 `reports/README.md`) -- 根目录:`README.md`(纯指路牌:设计/流程/当前位/待办四个链接,零规则重述)、`roadmap.md`(里程碑+迭代总表六列+顶部「当前位」节=现在做什么)、`stage.txt`/`review-mode.txt`(运行开关);仓库根禁止再设会话状态文件(细则见 doc-conventions 第 10 节) +- 根目录:`README.md`(纯指路牌:设计/流程/当前位/待办四个链接,零规则重述)、`roadmap.md`(里程碑+迭代总表六列+顶部「当前位」节=现在做什么)、`待办清单.md`(流水线唯一登记处,条目级待办与状态)、`体验验证清单.md`(需真人试玩才能下结论的验证项)、`stage.txt`/`review-mode.txt`(运行开关);仓库根禁止再设会话状态文件(细则见 doc-conventions 第 10 节) ## 规范导航(动手前先查表) @@ -48,24 +48,24 @@ | 系统设计 / 增删文档 | `design/gdd/02-系统清单.md`——根索引 + 中文规范名↔英文代号对照 | | 架构(唯一事实源) | `design/engineering/architecture/architecture.md`——历史决策沿革查 git commit log,不另设决策文档 | | 术语与已锁数值 | 规范名与定义 = `design/gdd/术语表.md`(全库唯一对照表,仅 owner 文档可修订);现行数值 = `game/data/tables/*.tres`;规则与取值域 = 各系统 owner 文档。冲突须显式提出,禁默默改值 | -| 现在做什么 / 待办与待裁 | 根 `roadmap.md` 顶部「当前位」节+迭代总表六列 · 待办唯一登记处 `design/gdd/06-待办清单.md` · 批次过程与结论查 git 提交信息与 `reports/` | +| 现在做什么 / 待办与待裁 | 根 `roadmap.md` 顶部「当前位」节+迭代总表六列 · 待办唯一登记处 `待办清单.md` · 批次过程与结论查 git 提交信息与 `reports/` | ## 硬性红线(勿违反;操作细则在 process-conventions.md 与各规约) - 主工作区禁止直接改动与提交——一切改动走独立 worktree(豁免:`.zcode/` 与 `.qoder/` 两份本机 harness 配置,实测均不入 git) -- **仓库根禁止设会话状态文件**(`active.md` 已废除)——现状看 roadmap「当前位」,待办看 06,过程看 git 提交信息,产出物看 `reports/`;任何文档禁止另设「当前状态快照」节,两处记同一件事必然漂移(细则见 doc-conventions 第 10 节) +- **仓库根禁止设会话状态文件**(`active.md` 已废除)——现状看 roadmap「当前位」,待办看待办清单,过程看 git 提交信息,产出物看 `reports/`;任何文档禁止另设「当前状态快照」节,两处记同一件事必然漂移(细则见 doc-conventions 第 10 节) - 测试执行两入口铁规——只有迭代 loop 开发与用户点名两个触发入口;其余会话零测试,需测试支撑先请示并注明未跑测 - 交付前验收 = 跑 `tools/run_all_gates.sh` **按改动域**全绿(唯一入口、唯一闸清单、唯一域划分,禁在文档另列);合回 master 由 worktree-guard 按 diff 推域校验回执强制(process-conventions §3) -- **两类批**——**迭代批**(代码实现,`/iter` 发射):**禁写 `design/` 整个目录**(含新增/修改/删除),设计文档对它只读、是写测试与实现代码的输入依据;产出物只准写 `reports/`;批末只跑代码域闸。**非迭代批**(工具/规则/文档改动):不占 roadmap 迭代号,按改动域跑闸。文档内容的落地走五段流水线相应段(文档设计段入口=doc-design 技能;登记条目格式由流水线闸强制) +- **两类批**——**迭代批**(代码实现,`/iter` 发射):**禁写 `design/` 整个目录与两份根流程清单(`待办清单.md`/`体验验证清单.md`)**(含新增/修改/删除),设计文档对它只读、是写测试与实现代码的输入依据;两份流程清单的条目状态只由流水线各段推进,实现批不得顺手改;产出物只准写 `reports/`;批末只跑代码域闸。**非迭代批**(工具/规则/文档改动):不占 roadmap 迭代号,按改动域跑闸。文档内容的落地走五段流水线相应段(文档设计段入口=doc-design 技能;登记条目格式由流水线闸强制) - 五段流水线铁律——一切工作按「登记 → 文档设计/美术设计 → 写需求卡片 → 迭代编排 → 实现」推进,段间不自动流转、每段转进由用户发令;编入迭代的卡片必须设计闭合+零待裁点,流水线闸 `tools/pipeline_gate.py` 强制(已注册进 run_all_gates.sh 文档域);实现段零裁断——卡片没写清=上游缺陷,停该卡退回上游,禁内联求裁(process-conventions §2,格式与状态机=doc-conventions §12) - MC/模拟:无数值改动零跑;档位硬闸见 `sim-data/README.md`「MC 采集档位表」,一档只能由用户发起 - 闸机轮次纪律:新码先孤立验证 → 出红只跑红件最小单元 → 长批先最小参数试车 → 开工扫坑册(process-conventions §6) - 变异验证——新增/改写验收函数必须变异变红才算验收成立;无变异红记录只写「已实现,拦截能力未证」(test-conventions §6) -- 中间产物吸收即死——结论先吸收进权威文档、未决先迁 06,文件即删且永不提交(doc-conventions 第 11 节) +- 中间产物吸收即死——结论先吸收进权威文档、未决先迁待办清单,文件即删且永不提交(doc-conventions 第 11 节) - **禁写变更记录**——文档与代码文件内一律禁设「版本历史/修订记录/变更记录/修改记录/更新记录/更新日志」节或表格,禁写「本版改了哪些条款」式逐版本叙述与 `# 2026-xx-xx 缺陷修批——` 式行内修订注记;沿革只进 git commit log。版本号可作文档现行身份标记留在文首状态行与正文引用中(doc-conventions 第 5 节,机检闸 gdd_lint R4 反转拦截) - 用语红线——一切对用户输出禁自造黑话,需要作者解释的词必须展开成完整白话句(doc-conventions 第 4 节三形态表) - 呈报四问(读后自检制)——向用户首次完整呈报一件事(需求/缺陷/方案/结论)时,写完先自查:读者只读这一段,能否不看原文答出——① 现状差在哪:现在是什么、缺什么;② 你建议做什么:做完预期什么效果、会动到哪些面;③ 为什么选这个做法:考虑过、放弃过哪些别的路;④ 做完怎么验证:哪些还有把握不足。哪问答不出就补哪问,禁靠加小标题凑数;三句话能说清的小件合并为三句:现状一句、建议与验证一句、没把握的一句;后续追问与推进不必重跑全框架 -- 真人检测只登记不阻塞——登记进 07 清单/实现报告即完成义务,禁以等目检为停工理由或收口前置 +- 真人检测只登记不阻塞——登记进体验验证清单/实现报告即完成义务,禁以等目检为停工理由或收口前置 - 文件头 = `##` 文档注释,介绍本模块是什么;禁写变更叙事(改动史查 git log);禁文档反向链接(code-conventions §1.4.1) - 数值单一事实源——玩法数值只存 `data/tables/`(.tres)经 ConfigDB 单点读取;禁数值字面量与自建 `load()` 表路径 - RNG 单点——禁 `randomize()`/自建 RandomNumberGenerator,随机只经 `RngService` 统一流 diff --git a/README.md b/README.md index c9ee03ea..a49f46dd 100644 --- a/README.md +++ b/README.md @@ -9,4 +9,4 @@ | 这个游戏设计成什么样 | [design/gdd/02-系统清单.md](design/gdd/02-系统清单.md)(GDD 根索引) | | 开发流程怎么走(五段流水线/批次纪律/验收闸) | [design/engineering/process-conventions.md](design/engineering/process-conventions.md)+[AGENTS.md](AGENTS.md) 规范导航表(每段一个技能入口) | | 现在做什么 | [roadmap.md](roadmap.md) 顶部「当前位」节 | -| 待办与待裁 | [design/gdd/06-待办清单.md](design/gdd/06-待办清单.md) | +| 待办与待裁 | [design/gdd/待办清单.md](待办清单.md) | diff --git a/design/art/art-assets-checklist.md b/design/art/art-assets-checklist.md index fb18c2f6..4c7c0bf7 100644 --- a/design/art/art-assets-checklist.md +++ b/design/art/art-assets-checklist.md @@ -2,7 +2,7 @@ > **性质**:表现层升级批与战斗表现批的生产侧清单——把散在战斗表现 / HUD框架 / 关卡节点地图 / 敌人系统里的资产需求收拢成一张可执行的工单视图,**兼资产维度单一登记处**。**规范效力归各 owner 文档**(战斗表现、美术圣经、04-美术音频方向),本文只补「生产视角的需求规格」,冲突时以 owner 文档为准。 > **建立**:2026-09-18 场景一(战斗画面呈现)讨论产物。**2026-09-22 GDD 过期账清偿批**:原 asset-checklist.md 并入本文后删除,本文自此为两份清单合并后的唯一清单;同批修正敌人键集/徽章数量/样张状态等过期事实(详见 art-bible 的 git 提交史)。**2026-09-22 §5 角色设计落地批**:剪影引用迁 art-bible §5.1、护甲区分方案落 §5.3(清偿两处待设计项)、提示词卡 v2.0 重生成(详见 art-bible 的 git 提交史)。**2026-09-23 复用盘点批**:立素材站复用渠道与复用闸(§0);新增 §3.4–3.6 三条此前漏登记的需求(增益状态效果图标 / 营地与元进度件 / 字体);各条目标注来源渠道。**2026-09-23 §5 抽离批**:角色设计内容迁独立文档 `character-design.md`(art-bible §5 自此为引用存根,小节号不变),本文 §5.x 剪影/护甲引用经存根仍可达;主角特征批(直剑→挖掘铲、加旗朱背旗)顺带,主角形象锚见 character-design.md §5.4。**2026-09-23 §6–9 补全批**:art-bible 四章成文(§6 环境/§7 UI/§8 资产规范/§9 参考与反参考);本文 §0 交付格式与像素尺寸行、参考图行、§6 依赖链顺带改指 §8/§9 现行。 -> **更新纪律**:各条目「现状」行顺带更新(未开始 / 候选已出 / 已裁决 / 已交付);做完不删条目,改状态。与 06-待办清单的联动:本文是资产维度明细,06 只留指路存根。 +> **更新纪律**:各条目「现状」行顺带更新(未开始 / 候选已出 / 已裁决 / 已交付);做完不删条目,改状态。与待办清单的联动:本文是资产维度明细,待办清单只留指路存根。 ## 0. 生产渠道、规格与风格宪法 @@ -17,7 +17,7 @@ **通用规格纪律**: - 交付格式 PNG 透明底;动画用序列帧或精灵表(SpriteFrames),帧数规格随样张批定(候选档已成文 art-bible §8.4)。命名规范候选草案见 art-bible §8.3。 -- **分辨率档位已定案(2026-09-22 用户确认):1280×800 + 1920×1080 两档**,窗口不可调、格边长按档位计算,后续调整走修订;像素画布已定暂定基准(**art-bible §8.2**:主角原图与战斗状态图 48×72、棋盘小人 32×32 二头身〔用户暂定〕;敌种立绘三档 48/64/96 候选;1× 基准整数倍缩放纪律;1920 档缩放策略与帧数规格待样张批,06-待办清单已登记)。 +- **分辨率档位已定案(2026-09-22 用户确认):1280×800 + 1920×1080 两档**,窗口不可调、格边长按档位计算,后续调整走修订;像素画布已定暂定基准(**art-bible §8.2**:主角原图与战斗状态图 48×72、棋盘小人 32×32 二头身〔用户暂定〕;敌种立绘三档 48/64/96 候选;1× 基准整数倍缩放纪律;1920 档缩放策略与帧数规格待样张批,待办清单已登记)。 - 程序化占位是现行结构冻结条款:资产未就位的槽位保持占位渲染,不空窗。 - **复用闸(♻ 渠道四道验收,一道不过不入包)**:① 色板量化——改色对齐 art-bible §4.1 token,不保留原包杂色;② 吸色检查——无 HSV 色相 300°–345°(紫赤禁入带);③ 灰度/色弱可辨——去色相后仍可辨且不与语义件混淆;④ 授权干净——CC0 优先,CC-BY 署名记入设置/关于页,license 不明的一律不用。 diff --git a/design/art/art-bible.md b/design/art/art-bible.md index 8c20509c..fb97b0e5 100644 --- a/design/art/art-bible.md +++ b/design/art/art-bible.md @@ -6,7 +6,7 @@ > 风格基调(2026-09-10 用户定稿):地牢题材但**非暗黑风**——轻快明亮的幻想冒险风,全年龄;像素风;角色 2~3 头身 > 参考池(用户审阅选定,三者相融):**Into the Breach**(网格信息分层;雷图棋盘呈现基准 = 其战棋地块质感 × 正俯视角,见 §3.2)× **Moonlighter**(明亮像素地牢质感)× **Peglin**(明快全年龄地牢色彩);参考截图存于 `design/art/references/`(三款×2 张,与点名池一一对应;gungeon 两张经 2026-09-22 裁决退场;正面取/弃与反面条款已成文 §9,反面图证待素材生成后另批增补) > 约束(2026-09-10 用户强调):本圣经是**纯表现层文档**——明亮轻快是美术风格,不是玩法成分。圣经禁止引入、暗示或预设任何玩法语义,不改变任何 GDD 已锁机制;凡表现层需要玩法钩子才能表达之处(如完美排雷检测、Boss 预警),一律标注「待 GDD 定夺」,圣经只规定"若有,则如何呈现"。GDD 机制与圣经冲突时,机制语义以 GDD 为准,呈现方案以本圣经为准 -> **条款验收标注纪律(2026-10-06 P2-4 用户拍板,全文书写规范)**:条款尾部按三档标注验收方式——**`←机检: <断言>`**(脚本可自动判定)/ **`←目检: <判据>`**(机器测不了,但看什么、算过有明确判据)/ **`←方向性`**(气质与方向原则,不承担验收);**新条款一律按此书写**,存量口号型条款分章补标(约 55%,06 挂账「口号型条款机检化批」分章推进、每章交付抽验);数值类条款推荐「**待定现用**」态(现行即执法、修订走登记,释义见 §4.1) +> **条款验收标注纪律(2026-10-06 P2-4 用户拍板,全文书写规范)**:条款尾部按三档标注验收方式——**`←机检: <断言>`**(脚本可自动判定)/ **`←目检: <判据>`**(机器测不了,但看什么、算过有明确判据)/ **`←方向性`**(气质与方向原则,不承担验收);**新条款一律按此书写**,存量口号型条款分章补标(约 55%,待办清单挂账「口号型条款机检化批」分章推进、每章交付抽验);数值类条款推荐「**待定现用**」态(现行即执法、修订走登记,释义见 §4.1) --- @@ -59,7 +59,7 @@ **判定与回退**:第 1 项不过 → 按原则二设计测试回退——先调格底明度档,复杂格底垫色牌兜底,禁止缩字号换字形逃避;第 2–4 项不过 → 修形不修数。样张通过 = 砖面形态与色板冻结;新增图类型/变异色板须重跑本测试(§4.3)。执行时机:正式砖面资产开工前;《HUD框架》以本节为引用依据(2026-09-07 门禁:样张测试并入 art-bible 执行)。 -**整屏样张闸(2026-09-29 v3.0 新增)**:格子样张验"格",整屏样张验"屏"——战斗屏/关卡屏/菜单屏/营地屏各出一张整屏样张,验收四项:①全部文字(含菜单/说明/tooltip/按钮)对其直接背景 ≥4.5:1(WCAG AA;大字〔≥18px 或加粗档〕底线 3:1、目标 4.5:1);②明度分层三档带成立(信息面层 > 世界中层 > 世界底层,层间灰度可分);③整屏焦点预算(§3.4:首焦唯一——数字区/立绘/主按钮,无第二焦点竞争;负空间服务焦点,不属空窗);④文字禁直接压纹理底(垫容器或罩层)。闸形 = **方向稿目检先行**(防"机检过闸但气质否决"式返工),目检过后机检冻结。执行时机 = 屏级视觉落码开工前;过闸前一切屏级视觉为占位临时态(§7.1 完成条款)。现行 §1.4 格子样张机检断言集中涉色牌/明度档条目随样张 v3 重跑同步改造(登记 06-待办清单)。 +**整屏样张闸(2026-09-29 v3.0 新增)**:格子样张验"格",整屏样张验"屏"——战斗屏/关卡屏/菜单屏/营地屏各出一张整屏样张,验收四项:①全部文字(含菜单/说明/tooltip/按钮)对其直接背景 ≥4.5:1(WCAG AA;大字〔≥18px 或加粗档〕底线 3:1、目标 4.5:1);②明度分层三档带成立(信息面层 > 世界中层 > 世界底层,层间灰度可分);③整屏焦点预算(§3.4:首焦唯一——数字区/立绘/主按钮,无第二焦点竞争;负空间服务焦点,不属空窗);④文字禁直接压纹理底(垫容器或罩层)。闸形 = **方向稿目检先行**(防"机检过闸但气质否决"式返工),目检过后机检冻结。执行时机 = 屏级视觉落码开工前;过闸前一切屏级视觉为占位临时态(§7.1 完成条款)。现行 §1.4 格子样张机检断言集中涉色牌/明度档条目随样张 v3 重跑同步改造(登记待办清单)。 > **样张 v2 记录(2026-09-28,四冻结生效)**:机检 16/16 全绿(扩展断言集:A3 图底分离 Δ≥55/F6 墙格顶面立面双明度带 Δ≥18/F7 整板悬崖 DEPTH_PX 与游戏渲染常量同源/A6 观感密度梯度均值 ≥4.70=v1 实测 4.09×1.15)。**四冻结**——①砖面形态:方案甲 21 瓦片+高墙感 D 投影档+整板悬崖(§3.2 高墙瓦片体系条定稿参数);②色板:小人蓝 #2E86DE/接触带微光 #D6ECFF/类型微光五组定稿(§4.1/§4.2);③动画方案:§8.4 帧数档冻结;④数字形制:色牌形制定稿(#F5EAD3 素色直角小牌+Fusion Pixel+字号 max(18, ceil(格边×0.5))+墨三档,§7.4)。产物=`artwork/mockups/sample-batch-v2-2026-09-28.png`,机检报告=git 提交 f9b0765;气质终审=批末用户目检(闸形 A,2026-09-27 拍板)。**(v3.0 注:四冻结之①砖面形态的数字承载面与④数字形制随色牌降级解冻,待样张 v3 重冻;②色板③动画维持冻结不变)** @@ -164,7 +164,7 @@ - **装饰变体(未开格氛围层)**:覆尘完整砖之上叠加裂纹/碎石斑/物件级点缀等装饰;2026-09-29 v3.0 物件级解禁——物件级装饰(小石块/陶片/骨殖等)须走**专属装饰形状家族**(与信息元素形状语言隔离、灰度下不与任何逻辑元素同形),数量配额按图类型定(候选 3–5 种,样张 v3 冻结),一律残缺、内凹、低对比而自然后退(§3.4);零信息纪律(分布随机、与雷/安/类型零相关、灰度下禁止制造新分类特征、分布每板一次跨轮不复掷)以原则三为准,此处不赘。←原三 - **结果整格表达(已开格)**:已开格按当格结果整格表达(结果清单见原则三);画法——产资源格的家族物件纹样用 §3.1 道具点剪影语言(直线几何体)角嵌于砖缘,砖心与数字字形占位区留白(已开格仍承载数字);危险格巢穴纹较已开格更凶一档,形状+颜色双通道不变。←原三;P3 - **未开格预读通道(微光单通道)**:类型预读 = 类型微光单通道(色相+明度双码,色带 §4.2);色弱类型主通道 = 微光明度梯度(组粒度——组间互辨;§2 微光明度例外);格内零角嵌/箭头/加号类附加形(2026-09-28 用户裁「微光格只留微光」,退役史见 git 提交史)。←原一;原三 -- **封印印记**:封印动作的叙事呈现 = **封印**(玩家可见专名,术语定义见 [术语表](../gdd/术语表.md)「封印」条;动作面见《排雷玩法》)——封印动作落在格上的印记称封印印记;封印色(§4.1,现行封印黑)与格内优先级栈位(§1.2)不变。封印特效(施印瞬间 + 印记常显形态)资产归清单 §4 演出类;封印印记纹理已落位(现行件=`seal_mark.png`,32×32 可选件)、字形占位退役(迭代 9 卡⑬已实现;原 06 债务条目已完成移除)。←原一;P2;术语批 2026-09-25;封印紫批 2026-09-26;封印黑批 2026-09-28 +- **封印印记**:封印动作的叙事呈现 = **封印**(玩家可见专名,术语定义见 [术语表](../gdd/术语表.md)「封印」条;动作面见《排雷玩法》)——封印动作落在格上的印记称封印印记;封印色(§4.1,现行封印黑)与格内优先级栈位(§1.2)不变。封印特效(施印瞬间 + 印记常显形态)资产归清单 §4 演出类;封印印记纹理已落位(现行件=`seal_mark.png`,32×32 可选件)、字形占位退役(迭代 9 卡⑬已实现;原待办清单债务条目已完成移除)。←原一;P2;术语批 2026-09-25;封印紫批 2026-09-26;封印黑批 2026-09-28 - **可挖域接触带微光(交互反馈层,2026-09-25 用户拍板)**:挖掘期,英雄格周界与可挖域(概念见《排雷玩法》动作合法性节;呈现义务见《HUD框架》可挖域指示)的接触面画呼吸微光——正交邻墙=该侧整条边,斜向邻墙=共享角点+向两侧各延伸半条边;光只画英雄格(空间)一侧、不进墙格(与装饰变体零冲突,数字砖心不涉);微光=空间的灯光边界(画法口径)。色相=蓝族浅一档(§4.2 蓝条;与主角蓝框的分层归样张批);呼吸=§2.1 挖掘期唯一在动元素,减动效停格。角点为斜墙与正交墙共享、不逐格归因,逐格指认=悬停金框(呈现交互归《HUD框架》悬停指示域)。←§2.1;§4.2;P1 - **墙体**:圆角砌块堆叠,禁尖刺装饰——尖刺专属危险语义,装饰禁止伪装逻辑差异。←原三 - **高墙瓦片体系(2026-09-26 定稿,样张批追认)**:未挖格=**一整块 32×32 自含凸起岩体**(方案甲核心定义);素材语义名——未开格素材=**墙瓦片**,已开格素材=**地面瓦片**(术语 2026-09-26 用户立)。**边界=墨线纪律**:墙瓦片与相邻格分界一律 1px 深墨线、直线贴格边、零锯齿;墨线职责=分隔,不追求与地面融合(Tiny Dungeon 样图实证调研后否决出局——TD 拼块套不进方案甲自含岩体定义,2026-09-25 终局维持方案甲;记录=git 提交 70d2320)。**光照=单一北受光**:北缘=墨线内侧 1px 微亮棱(就地取色提亮,禁宽亮带);西/东缘=墨线后直进纹理、不加修饰;南缘=墨线+立面窄暗条(约 1/3 格高,横层理叠石、禁竖条纹栅栏感)。**凹角**:角点单像素落线;南立面侧凹角加 1px 立面收头——带身与转角竖线同列收尾,禁悬空、禁突出(v9.1/v9.2 两版返工实证)。现行定稿=`game/assets/art/board/terrain_*`(16 唯一墙瓦片+5 地面瓦片变体;词表与查表逻辑见 `高墙瓦片词表(已落码 board_world.gd 查表,文件已退役)`)。**高墙感 D 投影档+整板悬崖(样张 v2 定稿 2026-09-28,用户 2026-09-27 四变体挑档)**:南临空墙格=立面口沿高光 2px `Color8(196,172,132)`+双段暗带(0.16/0.25 格边,黑罩 α0.60/0.82);北邻墙地面格=三段渐隐投影(顶带 0.22 格边,α0.28 起);整板悬崖=板底/右侧 `DEPTH_PX 8px` 暗面+列分隔竖缝+岩层横纹+口沿高光+接触 AO+底线收边+悬浮影(游戏 `board_world.gd` 同款结构件,样张脚本与游戏渲染常量同源——机检 F7 承载)。←原三;状态记录 164;样张 v2 批 2026-09-28 @@ -460,7 +460,7 @@ **(三)氛围层平滑件与抖动派并存(迭代 26 反哺④——Q5 已裁保平滑)** -- vignette / gradient_base / beams 三件程序化平滑渐变件**保平滑连续 alpha**(2026-10-13 grilling Q5 裁),与卡顶类型色带 DitherBand 的 Bayer 有序抖动派**并存不一致**——两派统一裁决留**整屏样张批**(§1.4;战斗一屏样张 P0 未开工,06 在册),本节只登记并存事实与裁决去向,不提前统一。 +- vignette / gradient_base / beams 三件程序化平滑渐变件**保平滑连续 alpha**(2026-10-13 grilling Q5 裁),与卡顶类型色带 DitherBand 的 Bayer 有序抖动派**并存不一致**——两派统一裁决留**整屏样张批**(§1.4;战斗一屏样张 P0 未开工,待办清单在册),本节只登记并存事实与裁决去向,不提前统一。 > **主题色值双源注记(迭代 25 反哺④)**:主题色值现存两处——`main_theme.tres` 字面量与 ui_kit 常量(卡片立项时已知代价,README 溯源表缓解)。长期收敛候选 = 程序化 Theme 生成回代码单点,属重构面、未排期;新增色值仍按现状双落并同批登 README 溯源表。 @@ -470,12 +470,12 @@ > **白话**:这一章是给所有出图者(人与脚本)的技术底线——多大的画布、什么格式、怎么命名。屏级格边长定值的裁决权在 battle.md;本节锁资产侧:分辨率档位、像素基准与缩放纪律、导出与命名、帧数规格。生产工单视图 = art-assets-checklist。 -> **定值单点纪律(2026-10-06 审计 §07-1 落规)**:全文数字定值只落在**两张表**——**§4.1 主色板**(全部色值+明度/饱和边界)与 **§8.2**(画布/体量/立绘源档/圆角率/缩放);其余章节一律**指路、禁复述数字**(修订改值只动单点处);character-design §5.5 为档位**语义**表(普通/精英/Boss + 例外),数值权威 = §8.2;存量双写复述随整备批(06 挂账)逐步收编。 +> **定值单点纪律(2026-10-06 审计 §07-1 落规)**:全文数字定值只落在**两张表**——**§4.1 主色板**(全部色值+明度/饱和边界)与 **§8.2**(画布/体量/立绘源档/圆角率/缩放);其余章节一律**指路、禁复述数字**(修订改值只动单点处);character-design §5.5 为档位**语义**表(普通/精英/Boss + 例外),数值权威 = §8.2;存量双写复述随整备批(待办清单挂账)逐步收编。 ### 8.1 分辨率档位与格边长口径 - **两档定案**:1280×800(基座)+ 1920×1080,窗口不可调;后续调整走修订。 -- **格边长口径**:按档位与板形计算——固定档位下格子量增加则格边长相应变小;现行 1280×800 基座锚点值 = 45px(10×10 板)/36px(12×12 板),扩板(13×13/14×14)换算值未定稿(1920 档已裁决全局等比缩放——迭代 9 卡⑮落码;原 06 分辨率债务条目已完成移除);装板可行性校验规则见《HUD框架》。 +- **格边长口径**:按档位与板形计算——固定档位下格子量增加则格边长相应变小;现行 1280×800 基座锚点值 = 45px(10×10 板)/36px(12×12 板),扩板(13×13/14×14)换算值未定稿(1920 档已裁决全局等比缩放——迭代 9 卡⑮落码;原待办清单分辨率债务条目已完成移除);装板可行性校验规则见《HUD框架》。 ### 8.2 像素基准与画布 diff --git a/design/art/character-design.md b/design/art/character-design.md index dfd73c33..9d64296b 100644 --- a/design/art/character-design.md +++ b/design/art/character-design.md @@ -9,7 +9,7 @@ 硬规则:**所有角色自带轮廓通道**——亮色描边(暖白族,禁黑描边)+落影底盘,识别不依赖所在背景。敌人不占格,剪影禁止借格底色成立;同一套剪影因此在棋盘、结算画面与任一战斗舞台通用,不为战斗表现未决的舞台问题付重画成本。←已锁事实;「禁黑描边」= 2026-09-20 提示词卡实践顺带固化 -**主角描边例外(2026-10-06 待决项 B 用户拍板——显式例外,非漂移)**:主角四态硬描边 = **深褐 `(40,19,13)`**,不入暖白族——深描边在浅砖面格底上对比更高、主角更突出;暖白达标率 0–28% 属例外内允许(敌人仍暖白族,实测达标 27–69%,不变)。素材不随本条修改;样张批(圣经 §1.4)终审复核例外成立性,复核义务登记 06 待办。 +**主角描边例外(2026-10-06 待决项 B 用户拍板——显式例外,非漂移)**:主角四态硬描边 = **深褐 `(40,19,13)`**,不入暖白族——深描边在浅砖面格底上对比更高、主角更突出;暖白达标率 0–28% 属例外内允许(敌人仍暖白族,实测达标 27–69%,不变)。素材不随本条修改;样张批(圣经 §1.4)终审复核例外成立性,复核义务登记待办清单。 四类角色 archetype 以高宽比/轮廓凹凸数/锐角数一眼区分(道具点——唯一非生物剪影——留在圣经 §3.1): diff --git a/design/engineering/architecture/architecture.md b/design/engineering/architecture/architecture.md index bf279d9c..67cfaeb8 100644 --- a/design/engineering/architecture/architecture.md +++ b/design/engineering/architecture/architecture.md @@ -196,7 +196,7 @@ | 域 | 闸 | 本批改动落在这些路径即属该域 | |---|---|---| | **代码域** | run_smoke、run_all、probe_gate `--click`、probe_gate `--full`、render_gate、static_scan、回放确定性对拍(条件件) | **唯一触发=`game/`**(游戏工程代码、测试、探针、场景、数据表)。2026-10-18 用户裁「跨领域执法禁绝」(提交 `7bdf53e3`)后,原 `tools/`、`artwork/` 两前缀不再把改动拉进代码域 | -| **文档域** | gdd_lint、doc_link_audit、doc_term_audit、流水线闸 | 一切非 `game/` 的路径:`design/`、根规则文件(`AGENTS.md`/`roadmap.md`)、`tools/` 工具脚本、`.zcode/` 配置、`sim-data/`、`reports/` | +| **文档域** | gdd_lint、doc_link_audit、doc_term_audit、流水线闸 | 一切非 `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 共享件例外);合回闸按 merge diff 路径推出应验的域,再校验回执的 `domain` 字段与新增红。代码域跑前先过**素材齐盘预检**——`game/assets/art/**` 与一切 `*.import` 边车都不入 git(2026-09-29 裁定),worktree 冷检出必空盘,空盘态冒烟 V1 成片假红、渲染闸更是一段 golden 都不比。 @@ -206,7 +206,7 @@ | 硬闸 | run_smoke | run_all | probe_gate | render_gate | static_scan | |---|---|---|---|---|---| | **退出码优先** | 已落实(闸①) | 已落实(套件 manifest expect 协议) | 已落实(`verdict` 函数逐段判退出码,PASS 串不作判据) | 已落实(段级退出码 + 取证双检) | 已落实(fail 聚合退出) | -| **SCRIPT ERROR 扫描** | 已落实(闸③,外部扫描——GDScript 无脚本错误陷阱 API,闸设在外部包装) | 已落实(入口内扫子套件输出;子进程的 stdout/stderr 须先落盘——`OS.execute` 管道在本机恒空) | 已落实(逐探针段 `tools/error_scan.py`,标记与 run_smoke 同源) | **缺失**(本批未收——判定主体是 golden 容差与取证存在性;登记 06) | 不适用(静态域无运行时错误面) | +| **SCRIPT ERROR 扫描** | 已落实(闸③,外部扫描——GDScript 无脚本错误陷阱 API,闸设在外部包装) | 已落实(入口内扫子套件输出;子进程的 stdout/stderr 须先落盘——`OS.execute` 管道在本机恒空) | 已落实(逐探针段 `tools/error_scan.py`,标记与 run_smoke 同源) | **缺失**(本批未收——判定主体是 golden 容差与取证存在性;登记待办清单) | 不适用(静态域无运行时错误面) | | **断言数下限** | 无独立下限(闸②摘要行必须在案,防「跑一半仍 PASS」;脚本错误吞断言路径由闸③兜住) | 已落实(`Kit.finish` 零断言返回专用退出码 2——与「断言失败=1」区分,防致命类套件的 expect 协议放过) | 已落实(退出码 0 但无该探针签名标记亦判红——防静默退出) | 不适用(golden 容差 + 取证存在性判定) | 不适用(逐规则命中判定;另有扫描面为空即判红的零命中自检) | 背景事实(run_smoke 头注在案):GDScript 运行时脚本错误不改进程退出码、不计入冒烟失败数、且静默中断所在函数剩余断言——2026-09-19 状态记录 83 实证「309 项 0 失败」实为断言未跑全。这是 SCRIPT ERROR 扫描必须存在于判定层的原因。 diff --git a/design/engineering/code-conventions.md b/design/engineering/code-conventions.md index b489a111..0d4b8fe0 100644 --- a/design/engineering/code-conventions.md +++ b/design/engineering/code-conventions.md @@ -92,5 +92,5 @@ ## 6. 流程纪律 1. **大改动三段走**:设计稿/伪代码 → 用户审阅 → 实现;实现禁止先于审阅。改动明细只进 git 提交信息,README 与代码内不写修改记录(doc-conventions 第 5 节「禁写变更记录」)。 -2. **实现批完成后的登记义务**:06 条目按 doc-conventions §12.1 推进状态,批次过程与结论进 git 提交信息与 `reports/`(根目录会话状态文件已废除,禁止再在其中登记条目)。 +2. **实现批完成后的登记义务**:待办清单条目按 doc-conventions §12.1 推进状态,批次过程与结论进 git 提交信息与 `reports/`(根目录会话状态文件已废除,禁止再在其中登记条目)。 3. **呈现层缺陷的教训回写 D1 GDD 设计输入**(信号载荷 schema / 场景级测试 / 时点状态可见性)。 diff --git a/design/engineering/concept-conventions.md b/design/engineering/concept-conventions.md index 0cceadac..e2fc2a33 100644 --- a/design/engineering/concept-conventions.md +++ b/design/engineering/concept-conventions.md @@ -23,7 +23,7 @@ **切分正例**(现行排雷循环即按此切分):棋盘是地图级对象,包含多个格;格是成员对象,危险格/安全格是它的枚举属性;格上可能挂的奖励或惩罚(格面资源)是独立对象,本体与规则归地图战斗资源与战斗结算,格只保留"有无资源资格"一个挂载位。反面基准:把奖励的类型、数值、极性全摊开写成格子的属性字段——奖励规则一改,棋盘文档就得跟着改,这便是没封装。 -**无权威文档,不下定义**:一个概念还没有权威文档时,任何其他文档都禁止替它下定义——只能引用概念名,并在 `design/gdd/06-待办清单.md` 登记「待落位」;谁先立权威文档,谁拿走全部定义权。(反例:某概念长期无权威文档,art-bible 复述、06 登记、需求卡片摘要三处各自给出口径,范围限定词在层层复述中丢失,最终放大成「全板常显」的错误事实。) +**无权威文档,不下定义**:一个概念还没有权威文档时,任何其他文档都禁止替它下定义——只能引用概念名,并在 `待办清单.md` 登记「待落位」;谁先立权威文档,谁拿走全部定义权。(反例:某概念长期无权威文档,art-bible 复述、待办清单登记、需求卡片摘要三处各自给出口径,范围限定词在层层复述中丢失,最终放大成「全板常显」的错误事实。) **与引用纪律的关系**:第 1 节管单个概念的边界与归属(概念级封装),第 2 节管概念之间、文档之间的引用(跨文档解耦)——先有封装,第 2 节的单点定义、反向边与删除 SOP 才有干净的作用对象。 @@ -40,7 +40,7 @@ | 依赖逐条列出 | 系统文档的「依赖与输出」节逐条列出本系统依赖的他人概念(规范名 + 链接)——这份清单就是删除概念时的影响面清单 | | 引用可查 | 需要某概念的影响面时,全仓搜索它的规范名即得;被引方在自己的「依赖与输出」节写明谁依赖它。人工维护的反向边清单已废止(2026-10-19 核出旧登记漏 7 份、多 1 份) | | 链接断了也好读 | 引用处的句子在链接失效后仍通顺完整(写"变异规则见《地形变异》",不把半截语义挂在链接里) | -| 待办单点登记 | 全项目待办事项单点登记于 `design/gdd/06-待办清单.md`:系统文档的「待办」节只留指路存根,禁止自建条目表;新增待办条目直接登记清单,裁决后改「状态」列留痕、不删条目 | +| 待办单点登记 | 全项目待办事项单点登记于 `待办清单.md`:系统文档的「待办」节只留指路存根,禁止自建条目表;新增待办条目直接登记清单,裁决后改「状态」列留痕、不删条目 | **引用格式**:一律 Markdown 相对链接,指向文件、必要时带节锚点(例:`[地形变异 · 变异类型](systems/排雷循环/地形变异.md#变异类型)`)——机械可查,死链可被工具检出。 diff --git a/design/engineering/doc-conventions.md b/design/engineering/doc-conventions.md index 3c39b101..c499bf99 100644 --- a/design/engineering/doc-conventions.md +++ b/design/engineering/doc-conventions.md @@ -92,7 +92,7 @@ | `03-内容规模.md` | 几个关卡、几种敌人、几种道具——做多少砍多少 | | `04-美术音频方向.md` | 参考图、参考游戏、风格关键词 | | `05-不做清单.md` | 明确写:这些我不要 | -| `06-待办清单.md` | 流水线唯一登记处:条目=登记元数据标题+四属性正文,状态随流水线段推进(格式与状态机见第 12.1 节);各系统文档「待办」节只留指路存根 | +| `待办清单.md`(仓库根) | 流水线唯一登记处:条目=登记元数据标题+四属性正文,状态随流水线段推进(格式与状态机见第 12.1 节);各系统文档「待办」节只留指路存根 | | `roadmap.md`(根目录) | 里程碑表+迭代总表,一行一迭代,记录编排与实现进度(六列格式见第 12.2 节) | **系统文档骨架**(`systems/` 下统一采用):文首引言(一句话定位+状态)/设计目的(2-4 句白话)/系统范围(负责/不负责两表)/在核心循环中的位置(字符画一行+两句白话)/核心规则(领域章节 ×2–6,每节一页纸)/依赖与输出(表格;引用纪律见 concept-conventions)/P0 最小闭环与 P1·P2 后置/调参表(取值域+provisional 标注)/验收标准(可验证判据)/待办(指路存根)。 @@ -105,23 +105,23 @@ **根目录 `active.md` 连同「会话状态唯一状态源」这条规矩一起废除。** 判据来自对 869 个历史会话的读写统计:整文件被读 448 次、平均每次 14 KB 进上下文,但会话里关于它的思考九成花在「追加条目前先查尾部编号防撞号」与「并行会话同时改它导致的合并冲突与丢弃」上,明确写「从它所载内容得知某事实」的只有 20 个会话;文件 45 KB 里约 95% 是别处已有权威源的重复说法、已失真陈述或已完结批次的历史叙述。体量闸只能测条目数与死链,测不出语义失真:10-15 清到 8.6 KB/3 条,10-17 已回到 40 KB,用户为「只写不删」连续三次发火,规矩照样失效。 -废除后的分工:**现在做什么**看根目录 `roadmap.md` 顶部「当前位」节;**待办与待裁**看 [06-待办清单](../gdd/06-待办清单.md)(唯一登记处);**批次过程与结论**看 git 提交信息与 `reports/`;**跨会话教训**看记忆库。禁止在仓库根新建同类状态文件,也禁止在任何文档里另设「当前状态快照」节——两处记同一件事必然漂移,这正是本次统计查出七条失实陈述的成因。 +废除后的分工:**现在做什么**看根目录 `roadmap.md` 顶部「当前位」节;**待办与待裁**看 [待办清单](../../待办清单.md)(唯一登记处);**批次过程与结论**看 git 提交信息与 `reports/`;**跨会话教训**看记忆库。禁止在仓库根新建同类状态文件,也禁止在任何文档里另设「当前状态快照」节——两处记同一件事必然漂移,这正是本次统计查出七条失实陈述的成因。 ## 11. 文档生命周期:吸收即死 -**活文档**=唯一事实源长期维护:GDD 树、art-bible 等定稿规范、术语表、架构文档(`design/engineering/architecture/architecture.md`)、本规范、06-待办清单、roadmap。**中间文档**=脚手架,寿命=迭代寿命:批需求卡片、机检/验收过程报告、调研/审计报告、模拟读数、迭代计划书、目检清单。为什么:了解游戏看 GDD,了解变更看 git;增量中间文档让版本管理失去意义,原始数据 dump 是化石不是证据。 +**活文档**=唯一事实源长期维护:GDD 树、art-bible 等定稿规范、术语表、架构文档(`design/engineering/architecture/architecture.md`)、本规范、待办清单、roadmap。**中间文档**=脚手架,寿命=迭代寿命:批需求卡片、机检/验收过程报告、调研/审计报告、模拟读数、迭代计划书、目检清单。为什么:了解游戏看 GDD,了解变更看 git;增量中间文档让版本管理失去意义,原始数据 dump 是化石不是证据。 | 规则 | 内容 | |---|---| | 吸收即死 | 中间文档结论写进权威文档(GDD 对应节/art-bible/术语表)那一刻,文件即删 | -| 未决先迁再死 | 未决内容先迁现行事实源(06/roadmap 卡/GDD 对应节),然后文档即死 | +| 未决先迁再死 | 未决内容先迁现行事实源(待办清单/roadmap 卡/GDD 对应节),然后文档即死 | | 永不入库 | 迭代出口后中间产物一律删除且不许提交;迭代进行中可暂存工作区,出口批一并清 | | 引用面口径 | 活文档对中间文档的指路阻塞删除:先改写指路句为结论内联或 git 提交号再删 | | 删除不留死链 | 中间文档删除后,任何现行文档禁止再留指向它的文件路径;改指结论或提交号 | | sim-data 白名单 | 只留 README、日志、分析工具 .py、现行 MC 对拍锚、设计文档 md;可再生原始数据不入库 | | 出口清理项 | 每迭代出口检查单必含:本迭代中间产物逐份核对(结论已吸收、未决已迁移)后删除 | -| 暂存地非档案库 | 中间文档有两处暂存地,入内文件默认到期即死:`reports/`(需求卡片+迭代产出物)、`design/research/`(调研/提案/评估/历史验收)。`design/` 各子目录不留验证截图——截图属一次性凭据,结论写进 06 或需求卡片后图像即弃(在途图放 `artwork/`,整目录不入 git);只有需要机器逐像素比对的基线图长期入库,落 `game/tests/golden/` | -| 落档必写接收方 | 新报告落档时头部必须写明接收方——`06-待办清单.md` 第几条,或哪张需求卡片。写不出接收方的不落文件,内容在会话里交付即可 | +| 暂存地非档案库 | 中间文档有两处暂存地,入内文件默认到期即死:`reports/`(需求卡片+迭代产出物)、`design/research/`(调研/提案/评估/历史验收)。`design/` 各子目录不留验证截图——截图属一次性凭据,结论写进待办清单或需求卡片后图像即弃(在途图放 `artwork/`,整目录不入 git);只有需要机器逐像素比对的基线图长期入库,落 `game/tests/golden/` | +| 落档必写接收方 | 新报告落档时头部必须写明接收方——`待办清单.md` 第几条,或哪张需求卡片。写不出接收方的不落文件,内容在会话里交付即可 | | 迭代实现报告 | 实现批收口的迭代级报告(各卡状态/代拍板追认单/GDD 反哺点清单),属中间文档,**落 `reports/` 不落 `design/`**(实现批禁写 `design/`,`reports/` 是其唯一可写目录):反哺点裁决落文吸收后按「证据只留最新」退役 | | 证据只留最新 | 测试证据只保留最新一次迭代或最新一轮同类审计版本;新证据落位后同批删上一份;待人清单过人闸后同规退役 | @@ -129,11 +129,11 @@ ## 12. 流程文档格式 -五段流水线(登记 → 文档设计/美术设计 → 写卡 → 迭代编排 → 实现,流程纪律见 `design/engineering/process-conventions.md` §2)靠流程文档运转:06-待办清单登记要做的事,roadmap 记录迭代编排结果,artwork 目录承载美术在途素材。本节是这些流程文档的格式与状态机权威,也是流水线闸(`tools/pipeline_gate.py`,自动检查 06 与 roadmap 两文件格式及互相引用的机检闸)的判据依据。 +五段流水线(登记 → 文档设计/美术设计 → 写卡 → 迭代编排 → 实现,流程纪律见 `design/engineering/process-conventions.md` §2)靠流程文档运转:待办清单登记要做的事,roadmap 记录迭代编排结果,artwork 目录承载美术在途素材。本节是这些流程文档的格式与状态机权威,也是流水线闸(`tools/pipeline_gate.py`,自动检查待办清单与 roadmap 两文件格式及互相引用的机检闸)的判据依据。 -### 12.1 06-待办清单条目格式与状态机 +### 12.1 待办清单条目格式与状态机 -06-待办清单是流水线的唯一登记处:要做的事先登记一条,随流水线段推进改状态,做完整条删除。一条条目分两层——**标题=登记元数据**(何时登记、从哪来、走哪条设计轨,登记后不再变),**正文=四个属性**(随进程演进)。 +待办清单是流水线的唯一登记处:要做的事先登记一条,随流水线段推进改状态,做完整条删除。一条条目分两层——**标题=登记元数据**(何时登记、从哪来、走哪条设计轨,登记后不再变),**正文=四个属性**(随进程演进)。 标题格式(尖括号处按实际填写): @@ -215,7 +215,7 @@ roadmap 由顶部里程碑表+迭代总表组成,迭代总表一行一个迭 ### 12.4 特批标记 -特批标记是流程格式例外的唯一放行凭证:`〔用户特批 YYYY-MM-DD 跳过××〕`。只有用户明示才能给,用于 06 条目状态与 roadmap 格(见 12.1、12.2)。 +特批标记是流程格式例外的唯一放行凭证:`〔用户特批 YYYY-MM-DD 跳过××〕`。只有用户明示才能给,用于待办清单条目状态与 roadmap 格(见 12.1、12.2)。 执行技能一律两段式: diff --git a/design/engineering/process-conventions.md b/design/engineering/process-conventions.md index dbd038f9..64fa77f9 100644 --- a/design/engineering/process-conventions.md +++ b/design/engineering/process-conventions.md @@ -20,15 +20,15 @@ | 段 | 入口技能 | 产出 | 出入口铁律 | |---|---|---|---| -| 一·登记 | 无(闸管格式) | 06-待办清单条目 | 条目=标题登记元数据+正文四属性(现状/缺口/归属/状态);标题登记后不再变,正文随进程演进。格式与状态机权威=doc-conventions 第 12 节 | -| 二·文档设计/美术设计 | doc-design(文档轨,兼任反哺点写入)/asset-ingest(美术录入;样张素材由用户主导产出) | GDD 文档或 art-bible/过审样张素材 | 用户提起或从 06 取出;会话内进行、用户主导、禁无监管自跑;经用户点头确认心智一致才许写入文档;完成判据=待裁点清零,带未裁点的是讨论稿;轨闭合凭据记入 06 现状清单(文档轨=文档路径+版本号,美术轨=art-bible 条款版本) | -| 三·写需求卡片 | req-card | 需求卡片 | 轨闭合后用户发令;新玩法/新系统/新内容必须有设计定稿前置,例外=工程直入四类(缺陷修复/工程债/测试基建/重构)凭证据跳过设计轨;卡片必经 grilling 多轮复核、零待裁点才成立;写完在 06 状态记「已写卡」,卡片路径记入现状清单(防遗忘) | +| 一·登记 | 无(闸管格式) | 待办清单条目 | 条目=标题登记元数据+正文四属性(现状/缺口/归属/状态);标题登记后不再变,正文随进程演进。格式与状态机权威=doc-conventions 第 12 节 | +| 二·文档设计/美术设计 | doc-design(文档轨,兼任反哺点写入)/asset-ingest(美术录入;样张素材由用户主导产出) | GDD 文档或 art-bible/过审样张素材 | 用户提起或从待办清单取出;会话内进行、用户主导、禁无监管自跑;经用户点头确认心智一致才许写入文档;完成判据=待裁点清零,带未裁点的是讨论稿;轨闭合凭据记入待办清单现状清单(文档轨=文档路径+版本号,美术轨=art-bible 条款版本) | +| 三·写需求卡片 | req-card | 需求卡片 | 轨闭合后用户发令;新玩法/新系统/新内容必须有设计定稿前置,例外=工程直入四类(缺陷修复/工程债/测试基建/重构)凭证据跳过设计轨;卡片必经 grilling 多轮复核、零待裁点才成立;写完在待办清单状态记「已写卡」,卡片路径记入现状清单(防遗忘) | | 四·迭代编排 | iter-plan | roadmap 迭代行 | 编排四查:①每卡卡片文件存在 ②每卡设计闭合凭据齐(或工程直入证据)③总估时 ≤2 周 ④写完 roadmap 行后跑流水线闸确认绿;编入未完成迭代,新开迭代行经用户确认 | | 五·实现 | iter | 代码与配置,可运行的游戏 | 需求卡片永不单独施工,统一由用户指定迭代号触发(=U0 开工令),按 iter 技能与本文 §3 执行;**本段是代码实现批:禁写 `design/` 与根规则文件,产出物只落 `reports/`(见 §3 第 13 条)**;设计权威文档(GDD/art-bible)批内一律不更新;完成人闸=实机目检清单+代拍板追认单登记交用户即完成批内义务 | -**实现段零裁断**:实现段的输入在编排段出口已锁死(卡片零待裁点+设计闭合凭据齐+编排四查过)。实现中冒出卡片没写清的分歧=上游缺陷——停该卡、06 状态回退+缺口补记,退回上游;禁自答、禁内联提问求裁断;该卡停摆不阻塞同迭代其他卡。环境故障与测试红走异常分级(自救重试/记录继续/停机呈报)。代拍板白名单保留:授权发生在卡片审问阶段,实现只执行预授权;批后追认单=备案确认。 +**实现段零裁断**:实现段的输入在编排段出口已锁死(卡片零待裁点+设计闭合凭据齐+编排四查过)。实现中冒出卡片没写清的分歧=上游缺陷——停该卡、待办清单状态回退+缺口补记,退回上游;禁自答、禁内联提问求裁断;该卡停摆不阻塞同迭代其他卡。环境故障与测试红走异常分级(自救重试/记录继续/停机呈报)。代拍板白名单保留:授权发生在卡片审问阶段,实现只执行预授权;批后追认单=备案确认。 -**流水线闸**:`tools/pipeline_gate.py` 机检 06-待办清单与 roadmap 两文件的格式与互相引用;已注册进 `run_all_gates.sh` 文档域。流程文档的条目格式、迭代行格式与状态机细则见 doc-conventions 第 12 节。 +**流水线闸**:`tools/pipeline_gate.py` 机检待办清单与 roadmap 两文件的格式与互相引用;已注册进 `run_all_gates.sh` 文档域。流程文档的条目格式、迭代行格式与状态机细则见 doc-conventions 第 12 节。 ## 3. 批次工作流标准清单 @@ -52,9 +52,9 @@ **完成** 10. **批末按域验收才合并**——在任务 worktree 内跑 `tools/run_all_gates.sh`,**按本批改动域选档**:本批改动触及 `game/`(游戏工程代码、测试、探针、场景)→ `--code`;不触及 `game/` 的一切改动(`design/`、根规则文件、`tools/` 工具脚本、`.zcode/` 配置等)→ `--docs`;同批混触 `game/` 与文档面 → 全量档不带参数。所选域全绿才合回 master。该脚本是全部验证闸的**唯一入口、唯一清单与唯一域划分**,闸件增减、分域调整都只改它;**本文与其他文档禁另列闸件清单**(清单散落多处正是 iter27 漏跑 `probe_gate --full` 的成因)。跑完写回执 `game/tests/.gates/receipt.json`(含 `domain` 字段),合回时由 worktree-guard 按 diff 路径推域强制校验(五况拦截:缺回执/quick 模式/回执 commit ≠ HEAD/域不覆盖本次改动/含新增红)。闸件(`tools/` 下机检脚本与闸壳)自身的改动不占合回全量——其质量义务=落批时的变异验证(test-conventions §6),闸真崩溃时合回闸 fail-closed(跑不出回执即拦),不以合回全量为兜底 11. **合并后主区按域复跑**——合并可能引入冲突或环境差异,落回 master 后按本批改动域复跑:触及 `game/` 的批=全量复跑(维持);纯文档域批=复跑文档域档(秒级),不再全量 -12. **批次完成后的登记义务**——合回 master 后按 doc-conventions §12.1 推进 06 条目状态(做完整条删除),涉及迭代编排的在 roadmap 迭代总表与顶部「当前位」节换代——执行入口=项目技能 batch-closure(批后收尾与中间文档退役),跨会话教训写记忆库。批次过程与结论由 git 提交信息承载,禁止再写会话状态文件(见 doc-conventions 第 10 节)。`design/` 与根规则文件(`AGENTS.md`/`roadmap.md`)实现批禁写,见 §13 -13. **文档同步闸(实现批禁写文档)**——实现批**禁写 `design/` 整个目录与根规则文件**,要往外交代的东西一律落 `reports/`:实现报告 `reports/iter-实现报告-<日期>.md`(各卡状态+实机目检总清单+遗留读数义务)、代拍板追认单 `reports/iter-代拍板-<日期>.md`、GDD 反哺点清单 `reports/iter-反哺点-<日期>.md`(每条写清哪个文件哪一节、改成什么、依据是什么)。设计权威文档(GDD/art-bible)**任何批都不直改**:用户在会话中逐点裁决后,由非迭代批(工具/规则/文档批)写入 `design/`(执行入口=doc-design 技能),并把反哺条目从 `reports/` 清掉(吸收即死;退役执行=batch-closure 技能)。机械面文档(roadmap 行/术语表/README 工具注)同样归非迭代批在合并前更新。反哺点未落地期间相关 GDD 节视为待反哺,读前先查 `reports/` 与 06;需求卡片必列「关联文档同步面」按两层标注 -14. **实机目检归用户,只登记不阻塞**——真人检测项登记进实现报告目检总清单与 07-体验验证清单即完成批内义务;禁把等目检当停工理由或完成前置 +12. **批次完成后的登记义务**——合回 master 后按 doc-conventions §12.1 推进待办清单条目状态(做完整条删除),涉及迭代编排的在 roadmap 迭代总表与顶部「当前位」节换代——执行入口=项目技能 batch-closure(批后收尾与中间文档退役),跨会话教训写记忆库。批次过程与结论由 git 提交信息承载,禁止再写会话状态文件(见 doc-conventions 第 10 节)。`design/` 与根规则文件(`AGENTS.md`/`roadmap.md`/`待办清单.md`/`体验验证清单.md`)实现批禁写,见 §13 +13. **文档同步闸(实现批禁写文档)**——实现批**禁写 `design/` 整个目录与根规则文件**,要往外交代的东西一律落 `reports/`:实现报告 `reports/iter-实现报告-<日期>.md`(各卡状态+实机目检总清单+遗留读数义务)、代拍板追认单 `reports/iter-代拍板-<日期>.md`、GDD 反哺点清单 `reports/iter-反哺点-<日期>.md`(每条写清哪个文件哪一节、改成什么、依据是什么)。设计权威文档(GDD/art-bible)**任何批都不直改**:用户在会话中逐点裁决后,由非迭代批(工具/规则/文档批)写入 `design/`(执行入口=doc-design 技能),并把反哺条目从 `reports/` 清掉(吸收即死;退役执行=batch-closure 技能)。机械面文档(roadmap 行/术语表/README 工具注)同样归非迭代批在合并前更新。反哺点未落地期间相关 GDD 节视为待反哺,读前先查 `reports/` 与待办清单;需求卡片必列「关联文档同步面」按两层标注 +14. **实机目检归用户,只登记不阻塞**——真人检测项登记进实现报告目检总清单与体验验证清单即完成批内义务;禁把等目检当停工理由或完成前置 15. **中间产物吸收即死**——细则见 AGENTS.md 硬性红线与 doc-conventions 第 11 节 ## 4. 测试执行两入口铁规(细则) diff --git a/design/engineering/test-conventions.md b/design/engineering/test-conventions.md index 244143e3..917e773f 100644 --- a/design/engineering/test-conventions.md +++ b/design/engineering/test-conventions.md @@ -83,4 +83,4 @@ - 「跑一遍没崩=通过」无效:测试绿只证明**当前代码没犯这个错**,不证明**犯了这个错会被抓住**;断言存在不等于断言执行。 - **脚本错误会静默中断所在函数的剩余断言,而套件仍报全绿**(机制事实):GDScript 无脚本错误陷阱 API,错误不改进程退出码、不计失败数。三处实证:①2026-09-19「309 项 0 失败」实为断言未跑全(状态记录 83);②敌人表行集纪律 10 条断言因定型数组赋值错误从未执行(迭代 29 修复后两条正向见红=夹具本缺锚行);③`Callable` 形参类型写错致解析函数返回 null、后续断言整段蒸发。 - 由此产生两条义务:**写闸件**按 §7 配三硬闸;**写验收函数**必须自证断言全数执行——变异验证(§6)为主证,反例实证(构造缺陷态改前判绿/改后判红)与零命中自检(扫描面为空即判红)为辅证。 -- **覆盖率不是目标**:行覆盖率度量缺失(Godot 无内建,第三方属新基建,是否引入 06 在册待裁);现行补洞=零指名单测清单+人工判定,判定可靠性靠上列自证手段,不靠覆盖率数字。 +- **覆盖率不是目标**:行覆盖率度量缺失(Godot 无内建,第三方属新基建,是否引入待办清单在册待裁);现行补洞=零指名单测清单+人工判定,判定可靠性靠上列自证手段,不靠覆盖率数字。 diff --git a/design/gdd/02-系统清单.md b/design/gdd/02-系统清单.md index a2e7f08c..f0b61b3e 100644 --- a/design/gdd/02-系统清单.md +++ b/design/gdd/02-系统清单.md @@ -13,8 +13,8 @@ | `04-美术音频方向.md` | 参考图、参考游戏、风格关键词 | | `05-不做清单.md` | 明确写:这些我不要 | | `术语表.md` | 全库专用术语的唯一对照表——危险格/安全格/同调位/RAP/GP/真视等定义+退役词对照(2026-10-11 建立,v1.0) | -| `06-待办清单.md` | 全项目待办事项的唯一登记处;各系统文档的「待办」节只留指路存根 | -| `07-体验验证清单.md` | 需要真人试玩观测的验证项登记处(与 06 分工:06 是"要拍板的事",本篇是"要玩过才知道的事");每条注明结论回流路径 | +| `待办清单.md`(仓库根,不属本树) | 全项目待办事项的唯一登记处;各系统文档的「待办」节只留指路存根 | +| `体验验证清单.md`(仓库根,不属本树) | 需要真人试玩观测的验证项登记处(与待办清单分工:待办清单是"要拍板的事",本篇是"要玩过才知道的事");每条注明结论回流路径 | | `08-Alpha版本标准.md` | Alpha 版本包含哪些东西的清单——里程碑 M3 的完成标准;只列条目不写内容,定义一律指路各权威文档(**已定稿 v1.4**,2026-10-13) | ## systems/ 五个循环 @@ -55,7 +55,7 @@ | `元进度.md` | 跨局成长(旧体系未单独成文) | 已定稿·已实现 | | `天赋树.md` | 跨局成长的树形承载(**结构/节点/数值/效果一律以该文档为唯一事实源——本表不复制其内容,只作指路**) | v0.8 换代定稿待实装(迭代 21 天赋树实装批,2026-10-11 用户令编入,开工门=U0 发令;需求卡片 v1.7) | | `生涯.md` | 主菜单一级的局外只读界面——跨局汇总、历史冒险回看、图鉴承接(冒险中数据回看的唯一承接处,P-C7 裁决) | 范围草案·待评审 | -| `锻造工坊.md` | 营地武器与护甲成长——武器锻造区(长剑/长枪/法杖)与护甲锻造区(轻甲/重甲/魔法护甲)各三条独立等级路线,钥石几何定价,一次冒险各选一件,满级特效留扩展位本期不做 | v0.5·**设计定案待实装(17 裁点已清零**——2026-10-12 B 组逐裁:1 丙/1a 一冒险一件武器+一件甲/2a 伪裁点消解/3b 敌方攻击缺省普通·克制反向当下生效/6 满级特效本期不做/8a 两区定名;2c·5a 于 v0.4 结案);开工门=17 裁点清零+用户发令,裁点门已满足——现状见 06-待办清单 | +| `锻造工坊.md` | 营地武器与护甲成长——武器锻造区(长剑/长枪/法杖)与护甲锻造区(轻甲/重甲/魔法护甲)各三条独立等级路线,钥石几何定价,一次冒险各选一件,满级特效留扩展位本期不做 | v0.5·**设计定案待实装(17 裁点已清零**——2026-10-12 B 组逐裁:1 丙/1a 一冒险一件武器+一件甲/2a 伪裁点消解/3b 敌方攻击缺省普通·克制反向当下生效/6 满级特效本期不做/8a 两区定名;2c·5a 于 v0.4 结案);开工门=17 裁点清零+用户发令,裁点门已满足——现状见待办清单 | | `秘宝.md` | 营地装配、整局冒险生效的角色机能件——操作包络加强(视野/行动点/刷新/挖掘距离等),不出角色战斗属性值、不改战斗结算机制 | 已定稿·跨局件(2026-10-10 自排雷循环迁入——解锁/装配/存档持久全在跨局侧) | ### 表现与支撑(`systems/表现与支撑/`) diff --git a/design/gdd/08-Alpha版本标准.md b/design/gdd/08-Alpha版本标准.md index 167186cc..860640da 100644 --- a/design/gdd/08-Alpha版本标准.md +++ b/design/gdd/08-Alpha版本标准.md @@ -109,13 +109,13 @@ | 关卡结算屏 | [level-clear](ux/level-clear.md) | 在役 | | 三选一(奖励节点 / 通关) | [node-reward](ux/node-reward.md) | 在役 | | 商店 | [shop](ux/shop.md) | 在役 | -| 状态面板(局内) | [06-待办清单](06-待办清单.md) | 部分在役(在役半=面板本体——迭代 17 卡③实装、2026-10-13 由「暂停层」改名;未结半=2026-10-16 用户令瘦身——去跨关解锁内容〔秘宝匣解锁态 12 行概览 / 天赋树已购概览〕、只留本局五件〔带的秘宝 / 已获专长 / 当前属性 / 现有 GP / 钥石总量〕;登记面=06「状态面板瘦身」专条) | +| 状态面板(局内) | [待办清单](../../待办清单.md) | 部分在役(在役半=面板本体——迭代 17 卡③实装、2026-10-13 由「暂停层」改名;未结半=2026-10-16 用户令瘦身——去跨关解锁内容〔秘宝匣解锁态 12 行概览 / 天赋树已购概览〕、只留本局五件〔带的秘宝 / 已获专长 / 当前属性 / 现有 GP / 钥石总量〕;登记面=待办清单「状态面板瘦身」专条) | | 冒险终局面板 | —— | 在役 | | 图例面板 | —— | 在役 | | 设置面 | [设置与本地化](systems/表现与支撑/设置与本地化.md) | 在役 | | 调试浮窗 | —— | 在役 | | UI 全局主题资源(引擎原生控件接管皮肤) | —— | 在役(迭代 25 · 2026-10-13 入库:game/assets/theme/main_theme.tres 挂 gui/theme/custom) | -| UI 按钮状态矩阵(悬停 / 按下 / 禁用 / 键盘焦点补齐) | [06-待办清单](06-待办清单.md) | 在役(迭代 26 入库:五态矩阵逐实例 override 补齐——悬停 modulate 提亮/禁用 α0.45 幽灵化/焦点 INK 2px 内缩 1px 环/危险钮本族按压态;键盘导航批量面归 Beta「棋盘战斗键盘/手柄输入」条连带点③) | +| UI 按钮状态矩阵(悬停 / 按下 / 禁用 / 键盘焦点补齐) | [待办清单](../../待办清单.md) | 在役(迭代 26 入库:五态矩阵逐实例 override 补齐——悬停 modulate 提亮/禁用 α0.45 幽灵化/焦点 INK 2px 内缩 1px 环/危险钮本族按压态;键盘导航批量面归 Beta「棋盘战斗键盘/手柄输入」条连带点③) | --- @@ -132,7 +132,7 @@ | 机器可读的呈现断言(对比度 / 结构) | `game/tests/` | 在役 | | 分辨率两档(1280×800 / 1920×1080) | [HUD框架](systems/表现与支撑/HUD框架.md) | 在役 | | 绘制调用数达标 | —— | 在役 | -| 真人试玩轮次 | [07-体验验证清单](07-体验验证清单.md) | 在役(义务维持;当前轮次未清) | +| 真人试玩轮次 | [体验验证清单](../../体验验证清单.md) | 在役(义务维持;当前轮次未清) | --- @@ -143,7 +143,7 @@ | 像素美术风格与色板 | [美术圣经](../art/art-bible.md) | 在役 | | 棋盘瓦片与格面资源图标 | [美术圣经](../art/art-bible.md) | 在役 | | 未开格类型微光(五组色相+明度档) | [HUD框架](systems/表现与支撑/HUD框架.md) | 在役(明度档 provisional 值登记见 art-bible 的 git 提交史,复核转正归战斗一屏样张) | -| 棋盘观感(第二 / 三关亮度与对比度) | [06-待办清单](06-待办清单.md) | 待做(2026-10-16 用户令编入迭代 30,序位③) | +| 棋盘观感(第二 / 三关亮度与对比度) | [待办清单](../../待办清单.md) | 待做(2026-10-16 用户令编入迭代 30,序位③) | | 立绘清晰度回退评估(是否改用高清图) | [角色设计](../art/character-design.md) | 待做(评估已结——2026-10-14 用户裁维持像素风、升级精细手绘像素、不回退高清图,裁决录=[美术审计-cursor会话存档](../research/美术审计-cursor会话存档-2026-10-14.md) §2.2;余=立绘按新口径重产+大小比例子题用户复核) | | 敌人立绘(全敌种) | [角色设计](../art/character-design.md) | 在役 | | 主角立绘三态 | [角色设计](../art/character-design.md) | 在役 | @@ -151,27 +151,27 @@ | 战斗演出链(弹道 / 受击 / 血条 / 灰化) | [战斗表现](systems/战斗循环/战斗表现.md) | 在役 | | 逐行结算排播 | [settlement-summary](ux/settlement-summary.md) | 在役 | | 减动效开关 | [设置与本地化](systems/表现与支撑/设置与本地化.md) | 在役 | -| 站桩帧动画 | [06-待办清单](06-待办清单.md) | 待裁 | -| 素材升档重产 | [06-待办清单](06-待办清单.md) | 待裁 | -| 全局纹理过滤设为邻近采样 | [06-待办清单](06-待办清单.md) | 在役(迭代 26 · 2026-10-14 入库:default_texture_filter=0+平滑渐变件三处显式 LINEAR 白名单,翻转面全枚举闭合) | +| 站桩帧动画 | [待办清单](../../待办清单.md) | 待裁 | +| 素材升档重产 | [待办清单](../../待办清单.md) | 待裁 | +| 全局纹理过滤设为邻近采样 | [待办清单](../../待办清单.md) | 在役(迭代 26 · 2026-10-14 入库:default_texture_filter=0+平滑渐变件三处显式 LINEAR 白名单,翻转面全枚举闭合) | | UI 贴图重构批(营地与元进度件出终稿) | [美术资产清单](../art/art-assets-checklist.md) | 待做 | | UI 字体补完(拉丁像素字专件 + 字重两档) | [美术圣经](../art/art-bible.md) §7.4 | 待做 | | 战斗一屏样张(界面美术的终稿闸) | [美术圣经](../art/art-bible.md) §1.4 | 待做(2026-10-16 用户令编入迭代 30,序位②) | -| UI 氛围层与九宫格切片观感修 | [06-待办清单](06-待办清单.md) | 部分在役(迭代 26 · 2026-10-14:光柱硬边半已修=连续 alpha 渐变;九宫格切片错位半未结——待素材尺寸核对,属美术线连带面) | -| UI 元素细节修(滑轨填充 / 图标垫块 / 留白 / 开发件外泄) | [06-待办清单](06-待办清单.md) | 在役(迭代 26 · 2026-10-14 入库:①滑轨填充随迭代 25 注销;余②图标垫块明度差降档/③商店+营地布局修/④诊断钮迁调试浮窗 全落地) | +| UI 氛围层与九宫格切片观感修 | [待办清单](../../待办清单.md) | 部分在役(迭代 26 · 2026-10-14:光柱硬边半已修=连续 alpha 渐变;九宫格切片错位半未结——待素材尺寸核对,属美术线连带面) | +| UI 元素细节修(滑轨填充 / 图标垫块 / 留白 / 开发件外泄) | [待办清单](../../待办清单.md) | 在役(迭代 26 · 2026-10-14 入库:①滑轨填充随迭代 25 注销;余②图标垫块明度差降档/③商店+营地布局修/④诊断钮迁调试浮窗 全落地) | --- ## 六、Alpha 不含 -下面这些明确不进 Alpha,写在这里防止回潮。逐条的理由见 [05-不做清单](05-不做清单.md) 与 [06-待办清单](06-待办清单.md)。 +下面这些明确不进 Alpha,写在这里防止回潮。逐条的理由见 [05-不做清单](05-不做清单.md) 与 [待办清单](../../待办清单.md)。 **与游戏内容无关的三项**(2026-10-13 用户裁:一律排 Beta)——它们不影响核心循环是否成立,缺了照样能联调、能通关,属打磨层: | 条目 | 理由出处 | |---|---| | 音频(音乐与音效) | 排 Beta(用户 2026-10-13 裁:与游戏内容无关);现行零音频资源、零播放代码 | -| 教学引导(含教学引导面) | 排 Beta([06-待办清单](06-待办清单.md) 教学引导节,2026-10-04 用户裁改排 Beta;2026-10-13 再确认) | +| 教学引导(含教学引导面) | 排 Beta([待办清单](../../待办清单.md) 教学引导节,2026-10-04 用户裁改排 Beta;2026-10-13 再确认) | | 多语言本地化 | 排 Beta(用户 2026-10-13 裁:与游戏内容无关);Alpha 只做最小设置面,不做多语言 | **其余不进 Alpha 项**: @@ -189,8 +189,8 @@ | 遗物式构筑协同 | [05-不做清单](05-不做清单.md) | | 战后自动回复 | [05-不做清单](05-不做清单.md) | | 反雪球机制 | [05-不做清单](05-不做清单.md) | -| 键盘 / 手柄输入 | [06-待办清单](06-待办清单.md)(排期归 Beta) | -| 数值统一标定(M4 数值批) | 2026-10-09 里程碑立规:M4 = Beta 阶段、M3 未由用户明令关闭前不排期(用户 2026-10-07 令移出迭代 18;2026-10-16 确认此裁长期有效)——06 各条「已编入 Alpha 收官 M4」措辞系旧口径残留 | +| 键盘 / 手柄输入 | [待办清单](../../待办清单.md)(排期归 Beta) | +| 数值统一标定(M4 数值批) | 2026-10-09 里程碑立规:M4 = Beta 阶段、M3 未由用户明令关闭前不排期(用户 2026-10-07 令移出迭代 18;2026-10-16 确认此裁长期有效)——待办清单各条「已编入 Alpha 收官 M4」措辞系旧口径残留 | | 连刷 / 换图资金跨战斗携带 | [05-不做清单](05-不做清单.md) | | 战斗节点地图类型差异化(更多地图主题) | 排 Beta 版本([playnote](../research/playnote.md),2026-10-13 裁) | diff --git a/design/gdd/systems/冒险循环/关卡节点图生成.md b/design/gdd/systems/冒险循环/关卡节点图生成.md index ecfaae6c..caad54b6 100644 --- a/design/gdd/systems/冒险循环/关卡节点图生成.md +++ b/design/gdd/systems/冒险循环/关卡节点图生成.md @@ -2,7 +2,7 @@ > 一句话:单关节点图怎么从固定配置变成逐局随机——图模板池、抽签与实例化 > 状态:**v0.5 台阶一已实施**(迭代 5 T5,2026-09-28 落 master 前挂 worktree m3-iter5-20260928——15 张骨架+node_map 扩签+首次冒险固定脚本+池内全模板校验+MC 分层出数,冒烟 576/0;文档本节规则与实现一致性以本批落地为准,台阶二/三仍后置) -> 旧版参考:无(旧体系未单独成文;事项自 2026-09-20 立项,池重生成已落地〔2026-09-29 返工批,二轮目检 15/15 过〕,原 06 条目已完成移除) +> 旧版参考:无(旧体系未单独成文;事项自 2026-09-20 立项,池重生成已落地〔2026-09-29 返工批,二轮目检 15/15 过〕,原待办清单条目已完成移除) ## 设计目的 @@ -118,7 +118,7 @@ 另两条暂缓理由顺带消解:**类型集未稳**——五类节点封闭枚举已随商店房批定稿,扩类走文档修订的既有通道对模板同样适用(模板 schema 跟随枚举走);**内容量不足**——台阶一的模板就是内容批,按内容批节奏逐张走,不设批量生产目标。 -## 拍板点(登记 [06-待办清单](../../06-待办清单.md),顺带更新条目) +## 拍板点(登记 [待办清单](../../../../待办清单.md),顺带更新条目) | # | 拍板点 | 状态 | |---|---|---| @@ -211,4 +211,4 @@ ## 待办 -本系统无未决待办(结构随机生成池已落地);后续新增待办统一登记 06-待办清单,本节不再逐条登记。 +本系统无未决待办(结构随机生成池已落地);后续新增待办统一登记待办清单,本节不再逐条登记。 diff --git a/design/gdd/systems/冒险循环/关卡节点地图.md b/design/gdd/systems/冒险循环/关卡节点地图.md index fda8d77e..13508256 100644 --- a/design/gdd/systems/冒险循环/关卡节点地图.md +++ b/design/gdd/systems/冒险循环/关卡节点地图.md @@ -65,7 +65,7 @@ 呈现侧口径(2026-09-17 用户拍板):节点图的画面表达走**方块地牢观感**——节点画成地牢房间的方块、连线画成通道——但逻辑拓扑就是本文的节点图,不产生任何额外选路或探索语义。关卡画面本体即节点链进度的呈现载体(选路覆盖层的常驻形态,节点态直接读图:已过暗金 / 当前金 / 候选下一跳通道亮金 / Boss 封印黑描边(旗朱→封印紫→封印黑 #000000,2026-09-28 用户拍板现行)),不另设进度条组件;视觉规格归 [HUD 框架](../表现与支撑/HUD框架.md)。 -**商店覆盖层呈现**(呈现 spec:[design/gdd/ux/shop.md](../../ux/shop.md) v1.0,2026-09-30;**v1.5 注记**——pool 模式货架面=共享池三选一同构卡〔进店抽 3/买 1 全重抽/空架售罄态〕,与三选一奖励同一交互语言;legacy 固定三件面随对照模式保留。**v1.5-a 注记(2026-10-04 用户裁)**:~~库存余量就近~~ **库存余量不呈现**(货架卡不带「库存余 N/∞」字样——库存语义仍在共享池令牌库,仅呈现退役;独立刷新机制另见 06「商店独立刷新机制」条):兑付 = 打开商店覆盖层(模态)——货架卡陈列、GP 余额读数、购买/离开;离开后兑付确认回选路。本节锁编排面(何时开/何时关/回选路),呈现细节归 spec;定价数值归[难度曲线与Boss](难度曲线与Boss.md)(shop.tres)。 +**商店覆盖层呈现**(呈现 spec:[design/gdd/ux/shop.md](../../ux/shop.md) v1.0,2026-09-30;**v1.5 注记**——pool 模式货架面=共享池三选一同构卡〔进店抽 3/买 1 全重抽/空架售罄态〕,与三选一奖励同一交互语言;legacy 固定三件面随对照模式保留。**v1.5-a 注记(2026-10-04 用户裁)**:~~库存余量就近~~ **库存余量不呈现**(货架卡不带「库存余 N/∞」字样——库存语义仍在共享池令牌库,仅呈现退役;独立刷新机制另见待办清单「商店独立刷新机制」条):兑付 = 打开商店覆盖层(模态)——货架卡陈列、GP 余额读数、购买/离开;离开后兑付确认回选路。本节锁编排面(何时开/何时关/回选路),呈现细节归 spec;定价数值归[难度曲线与Boss](难度曲线与Boss.md)(shop.tres)。 ### 行进与选路:兑付后确认,选路就是行进 @@ -174,4 +174,4 @@ Boss 兑付(胜利或英雄死亡)触发关卡收束点,此后不再有选 ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 diff --git a/design/gdd/systems/冒险循环/冒险结构.md b/design/gdd/systems/冒险循环/冒险结构.md index 7dae708f..2cd50169 100644 --- a/design/gdd/systems/冒险循环/冒险结构.md +++ b/design/gdd/systems/冒险循环/冒险结构.md @@ -170,7 +170,7 @@ GP(显示名「GP」)是冒险内的一次性属性提升货币:战斗胜 **奖励节点三选一池(结构层——池机制事实源=[奇物](奇物.md)「池结构与抽取」节,2026-10-11 迭代 20 案D 换代)**:池 = 四级令牌库 70/25/9/0=104 张(案D——普通打底/优秀·稀有做翼/传说惊喜位空集;曝光槽 = 三选一 2 格全池 + 1 格优秀档以上子池,令牌 = 出现次数上限、概率与已拿上限解耦;构成数字与抽取细节全读[奇物](奇物.md)与 `adventure.tres`,provisional 归[难度曲线与Boss](难度曲线与Boss.md)曲线调参批,本节零复制)。**池为冒险级单例**(迭代 10 追加批):关卡内奖励节点的三选一与商店货架共享同一令牌库(同库同摘牌),库存 = 剩余令牌数;消费 reward_pick 封闭随机流(主种子派生、[数据配置](../表现与支撑/数据配置.md)口径),同种子同操作序列同三选项可复放;**MC 策略 316-f**:autoplay 1 级优先度=最稀有(rarest>rare>common)、2 级=最左。断点附随件承载池余库逐枚还原;兑付语义归[关卡节点地图](关卡节点地图.md)。 -**秘宝件受同调位约束**(2026-10-09 注:道具件已随迭代 11 第①批 T7 出池——三选一/奖励节点/战斗内渠道现行零道具件投放,下述渠道约束与替换交互无现役触发面,保留作渠道恢复时的契约口径;同调位读数现行事实源=attunement_growth.tres 谓词表实时求值):道具持有上限 = 同调位数。读数源 = 同调位里程碑谓词表 attunement_growth.tres 实时求值(0 起步、硬上限 3、增长 = 通关次数 + Boss 击杀数——同调实施批 2026-10-03 落地,过渡读数源 transitional_sync_slots 已顺带退役;原提案八拍板 git 57da58c 已退役)。获取渠道约束形态(迭代 10 过渡承载):三选一道具件超位触发**替换交互**(现有件与新件 N+1 选 N——丢任一原有件腾位收新,或放弃新件不获取;终态恒 ≤ 同调位);奖励节点与战斗内渠道超位**不授予**(候选拒绝 + 掉落沉没,逐行归因留痕)——停点渠道全覆盖的替换交互随同调实施批统一完成(原 06 条目已随完成移除)。 +**秘宝件受同调位约束**(2026-10-09 注:道具件已随迭代 11 第①批 T7 出池——三选一/奖励节点/战斗内渠道现行零道具件投放,下述渠道约束与替换交互无现役触发面,保留作渠道恢复时的契约口径;同调位读数现行事实源=attunement_growth.tres 谓词表实时求值):道具持有上限 = 同调位数。读数源 = 同调位里程碑谓词表 attunement_growth.tres 实时求值(0 起步、硬上限 3、增长 = 通关次数 + Boss 击杀数——同调实施批 2026-10-03 落地,过渡读数源 transitional_sync_slots 已顺带退役;原提案八拍板 git 57da58c 已退役)。获取渠道约束形态(迭代 10 过渡承载):三选一道具件超位触发**替换交互**(现有件与新件 N+1 选 N——丢任一原有件腾位收新,或放弃新件不获取;终态恒 ≤ 同调位);奖励节点与战斗内渠道超位**不授予**(候选拒绝 + 掉落沉没,逐行归因留痕)——停点渠道全覆盖的替换交互随同调实施批统一完成(原待办清单条目已随完成移除)。 最后一关通关不发三选一与部分回血:没有下一战可受益——只做冒险完成结算,末关 Boss 钥石照常入账。设计意图:清库之后才兑付、末关不兑付,都是从「奖励只朝下一战生效」这一条推出来的。 @@ -300,4 +300,4 @@ GP(显示名「GP」)是冒险内的一次性属性提升货币:战斗胜 ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 diff --git a/design/gdd/systems/冒险循环/奇物.md b/design/gdd/systems/冒险循环/奇物.md index 19f0dea7..bc2d313e 100644 --- a/design/gdd/systems/冒险循环/奇物.md +++ b/design/gdd/systems/冒险循环/奇物.md @@ -63,7 +63,7 @@ | 陷阱爆发 | on 踩雷:全体存活敌受 雷伤×倍率 直伤 | 角色与怪物互相吃伤害;倍率 >1 系结构锚(引爆有代价、回报须更高),数值归调参批(扩签:雷罚伤害量) | | 血蜜 | on 踩雷:回复 N 生命 | 引爆仍然净亏血、只是亏得慢;比值 <1 系结构锚,N 归调参批 | | 石肤 | on 受伤:AC +1(本场累计,上限 M) | 受击成长型护甲——越挨打越硬;恒定减伤形态被否(用户裁「太硬霸」),M 归调参批 | -| 背水 | when 生命 ≤50%:受伤额外 −N | 风险联动减伤——低血不再是纯劣势;自爆流刀口舔血兜底(扩签:生命比例〔条件事实——实现前置需求,06 在册〕) | +| 背水 | when 生命 ≤50%:受伤额外 −N | 风险联动减伤——低血不再是纯劣势;自爆流刀口舔血兜底(扩签:生命比例〔条件事实——实现前置需求,待办清单在册〕) | **踩雷转化对账锚(自爆流 kill-switch,2026-10-11 用户裁顺带登记)**:踩雷的净血账期望必须为负——雷伤 > 血蜜回复 + 其余转化件的血当量;对账归调参批,两轮数值迭代压不住则砍血蜜。防「见雷就踩」退化(喂雷流 R5 甲教训同源);主动/误踩不判定(用户裁:不预判玩家意图,拿件自选收益最高的操作)。 @@ -372,7 +372,7 @@ #### 2.5 在册事项 -现行实现里**三条渠道共用同一个候选池**(商店货架按 2.4 可计算条件切边去掉计价物),三个分类出现条件一样、只有出现概率不同——上表渠道分工中的**凭证形式(非 Boss 渠道给凭证 + 保底限购)已随迭代15② 入表实装**(见 2.2 与调参表);**Boss 渠道直接给专长已裁随专长实装批本批落地**(2026-10-11 用户裁,不再分期)。相关的实施批次登记在 [06-待办清单](../../06-待办清单.md) 的 BD 分层条目下,本文件不复制。 +现行实现里**三条渠道共用同一个候选池**(商店货架按 2.4 可计算条件切边去掉计价物),三个分类出现条件一样、只有出现概率不同——上表渠道分工中的**凭证形式(非 Boss 渠道给凭证 + 保底限购)已随迭代15② 入表实装**(见 2.2 与调参表);**Boss 渠道直接给专长已裁随专长实装批本批落地**(2026-10-11 用户裁,不再分期)。相关的实施批次登记在 [待办清单](../../../../待办清单.md) 的 BD 分层条目下,本文件不复制。 **池结构选型澄清(2026-10-11)**:池结构正主=案 D(v3.3 写入文档,用户定夺在案);「概率与上限解耦」的实现路径(v3.4 在册三案)系**实装侧自选项,非用户裁定项**——按「实现设计不定于现在」的原裁定,实装批内依代码事实自选,不再上问。 @@ -425,7 +425,7 @@ - **P0(已实现)**:三个分类可定义 → 进入候选池 → 在渠道上被选中 → 当局生效 → 收束清零。 - **P1 后置**:三条渠道按第 2 节分工——凭证形式(非 Boss 渠道给凭证+保底限购)已随迭代15② 入表实装(见调参表),其余分工(Boss 渠道直接给专长等)待实施。 -- **P2 后置**:商店里的攻击类型转换服务;喂雷玩法是否保留(尚未拍板,登记在 [06-待办清单](../../06-待办清单.md))。 +- **P2 后置**:商店里的攻击类型转换服务;喂雷玩法是否保留(尚未拍板,登记在 [待办清单](../../../../待办清单.md))。 ## 调参表 @@ -461,4 +461,4 @@ ## 待办 -全部待办单点登记于 [06-待办清单](../../06-待办清单.md)(BD 分层条目、命名统一后续条目),本节不复制。 +全部待办单点登记于 [待办清单](../../../../待办清单.md)(BD 分层条目、命名统一后续条目),本节不复制。 diff --git a/design/gdd/systems/冒险循环/难度曲线与Boss.md b/design/gdd/systems/冒险循环/难度曲线与Boss.md index 30ec5bc9..b95413e4 100644 --- a/design/gdd/systems/冒险循环/难度曲线与Boss.md +++ b/design/gdd/systems/冒险循环/难度曲线与Boss.md @@ -107,7 +107,7 @@ MVP 行值并不逐式现算,而是按此式量级直填经切片验证过的 ### 期望值带:三条定稿的验收带 -单战判定之上还有"整关长什么样"的验收基准。下面三条带是定稿口径;调参后任一条越带都必须回滚或登记,禁止静默出带。带子按模拟口径定义——即调参期批量模拟器的读数口径;真人与模拟者的偏差另行登记标定义务(登记 [06-待办清单](../../06-待办清单.md))。 +单战判定之上还有"整关长什么样"的验收基准。下面三条带是定稿口径;调参后任一条越带都必须回滚或登记,禁止静默出带。带子按模拟口径定义——即调参期批量模拟器的读数口径;真人与模拟者的偏差另行登记标定义务(登记 [待办清单](../../../../待办清单.md))。 | 带 | 定稿口径 | 含义 | |---|---|---| @@ -163,7 +163,7 @@ GP 与商店房随 2026-09-20 GP+商店房批落地,给难度引入第三族 商品价格(legacy 对照) = 基价 + 关级价格加成 + 步长 × 已购档数 ``` -定价锚定口径:商品价格按"正常运气可购档数 / 运气极好可购档数"两读数的数学期望制定(期望读数进商店表批注)——正常运气的玩家买得到成长保底档,运气极好也不至于全表买穿,两个失速态都不出现。**v0.22 换代注记(迭代 11 第②批)**:A=店内递增 ≫ b=跨关递增的方向裁决随 06「GP 商店房重构」条落定;A/b 具体系数原裁决=game-balancer 研究后用户拍板(P5 甲),迭代 11 第②批依零人工令改 provisional 投值 1.8/1.1+后置追认(追认单随迭代 11 出口包,研究归调参批复核);ceil 向上单一取整(玩家不利向)。 +定价锚定口径:商品价格按"正常运气可购档数 / 运气极好可购档数"两读数的数学期望制定(期望读数进商店表批注)——正常运气的玩家买得到成长保底档,运气极好也不至于全表买穿,两个失速态都不出现。**v0.22 换代注记(迭代 11 第②批)**:A=店内递增 ≫ b=跨关递增的方向裁决随待办清单「GP 商店房重构」条落定;A/b 具体系数原裁决=game-balancer 研究后用户拍板(P5 甲),迭代 11 第②批依零人工令改 provisional 投值 1.8/1.1+后置追认(追认单随迭代 11 出口包,研究归调参批复核);ceil 向上单一取整(玩家不利向)。 | 杠杆位 | 口径 | 说明 | |---|---|---| @@ -175,7 +175,7 @@ GP 与商店房随 2026-09-20 GP+商店房批落地,给难度引入第三族 公式语义与 GP 归[冒险结构](冒险结构.md)(GP 节),商店房编排归[关卡节点地图](关卡节点地图.md);行值读 `data/tables/shop.tres`,全部 provisional 归本文曲线调参批。 -**分层验收 defer(2026-09-20 用户拍板成文)**:按"商店存在与否"分层的通关率验收——MC 双格(shop=off 现行基线 / shop=on 购买画像)、shop=on 的带平移量、商店属性提升的换算率登记(换算率强条目纪律同类)——**全部随曲线调参批执行**,与「基线通关率越带」同窗(原「L2 Boss 承伤微越带」「大奖励数值随难度曲线联动」两 06 条目已完成移除——前者 2026-09-28 读数自愈、后者随迭代 10 大奖励退役失义)。执行前 shop=off 续用现行带判读,shop=on 读数只登记不判读、禁止用 shop=off 读数外推 shop=on。L3 首遇绿档冒烟断言仍按成长代理档口径,不因商店批改判。**v0.22 注记(迭代 11 第②批)**:shop=off 对照 = legacy 固定三件模式(MC 逐项比对 off_n60 逐位,迭代 11 第②批 T5);shop=on 首锚 = 共享池货架面 N=60 双策略(`runsum_m4iter11b_t5shopon_n60_20261003.jsonl`,attune=off 同种子配对)——带平移判读仍归调参批,终局池读数(pool_stock)随行只测不判。 +**分层验收 defer(2026-09-20 用户拍板成文)**:按"商店存在与否"分层的通关率验收——MC 双格(shop=off 现行基线 / shop=on 购买画像)、shop=on 的带平移量、商店属性提升的换算率登记(换算率强条目纪律同类)——**全部随曲线调参批执行**,与「基线通关率越带」同窗(原「L2 Boss 承伤微越带」「大奖励数值随难度曲线联动」两待办清单条目已完成移除——前者 2026-09-28 读数自愈、后者随迭代 10 大奖励退役失义)。执行前 shop=off 续用现行带判读,shop=on 读数只登记不判读、禁止用 shop=off 读数外推 shop=on。L3 首遇绿档冒烟断言仍按成长代理档口径,不因商店批改判。**v0.22 注记(迭代 11 第②批)**:shop=off 对照 = legacy 固定三件模式(MC 逐项比对 off_n60 逐位,迭代 11 第②批 T5);shop=on 首锚 = 共享池货架面 N=60 双策略(`runsum_m4iter11b_t5shopon_n60_20261003.jsonl`,attune=off 同种子配对)——带平移判读仍归调参批,终局池读数(pool_stock)随行只测不判。 ### Boss 设计:食人魔酋长与关底血量锚 @@ -263,7 +263,7 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板 | P1 | 挖掘风险不等式与清图支配性对账重跑 | **挖掘风险不等式半边已完成(2026-10-05 判式换代批,迭代14②号卡)**——判式三层重立写入文档+条件二封印溢价机制闭合+β 带判读制度化(残留=u=3 β=1.17 微破下限登记态,不强制回滚;δ 敏感度判读顺带出口报告),本行对挖掘风险不等式的「重跑义务」改判读回执:后续调参按 β 带检算执行,不再立独立重跑批。清图支配性已于 2026-09-19 按现行值链重跑(裁决②"非支配设计态"维持——缺口收窄主读数 L1≈24/L2≈45 当量〔u=1〕,设计权威回执=git 提交 2ca3e20,重跑入口 tools/clear_dominance_audit.py);调参批执行时按当期行值顺带重跑 | | P1 | 真人通关率修正系数标定 | 带按模拟口径定义;试玩批次实测真人显著强于模拟者,系数待后续试玩批次定量 | | P1 | 迭代 10 奖励重构带重扫义务 | 恢复经济收紧(通关血回满→部分回血 20%,难度上压方向)+ 局内成长节奏变动(三选一件值/权重/次数上限 knob 全读冒险表;AP 件 = 每场战斗开始首轮 +1 AP 的强度敏感轴)——通关率带重扫随曲线调参批现行窗执行;Boss 钥石掉落重锚(首杀 3/复杀 2)连带元进度产出标定义务重开(归元进度设计批) | -| P1 | 完美策略档的结构性加难杠杆 | 数值杠杆对完美档已被实测证伪,结构候选未裁决(登记 [06-待办清单](../../06-待办清单.md)) | +| P1 | 完美策略档的结构性加难杠杆 | 数值杠杆对完美档已被实测证伪,结构候选未裁决(登记 [待办清单](../../../../待办清单.md)) | | P2 | 精英节点完整语义与修饰乘数表首行 | 随[关卡节点地图](关卡节点地图.md)定稿联动;首个使用场景 = 精英节点;精英怪设定三特征已登记(迭代 10 批,见「曲线雕刻」表注),钥石掉 1 个预留挂钩 meta.tres boss_keystone 精英行(随实装批落) | | P2 | 区间平移换算率定稿 | 接口启用形态已定稿(2026-09-18 元进度定稿批);剩余面 = 首版三行折算数值随[元进度](../跨局循环/元进度.md)设计批模拟读数标定 | | P2 | 全局作用域变异的投放计划 | **首发已落地(2026-10-04 全局作用域变异首发批,迭代 14 ③号卡)**——现行=L2/L3 Boss 图恒定贫矿脉(unlock_level=2 起,第 1 关 Boss 免疫=L1 教学保护);本行降级为「后续型扩展计划」:新全局型(精英图首行/案D 冻土/案B 诡雷远期)逐关固定演进,随关卡扩展登记;带 A(全局变异)收敛判读归全局难度批(Beta 阶段,未排期)杠杆表(Q4 甲——落地批读数只测不判) | @@ -295,7 +295,7 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板 | 池权重 | 权重即旋钮:抬特殊技权重 = 抬输出频率,EV 随之重锚;各敌种行集读表 | | 技能冷却(拍) | 逐技能行读表;普攻冷却恒 0 不可配(空池不可能的结构前提——域校验锁死);撕咬 = 与突刺同倍率错开冷却轴的高频小爆发轮廓;毒爆 = 蛛化卓尔精灵专属池独占技 | | 保底 M | 全局单旋钮,读技能表 pity_threshold;连续 M 拍执行普攻 → 下拍必出特殊技;单特殊技低权重池受保底支配 | -| 池 EV 锚 | 静态份额与含闸长期速率实测读数登记于调参日志(EV 重锚与权重投值随本表修订)。**2026-09-19 节奏体验验证批登记**(60 distinct seeds × 双策略 × 两关,tools/skill_rhythm_audit.py——20 种子以下批次有种子偏置假象,读数须 ≥50 种子):特殊技执行份额 对表成立——地精 10.4%(静态 10%)/ 地精一伙 8.4% / 熊地精系 28.9–42.4% / 巨蜘蛛 34.8% / 酋长 28.9% / 卓尔 35.4%;**L2 池含闸速率抽样复核完成**(上项即含闸读数);保底越界 0/247(间隔 4 = M=4 合法上界);过涝信号 8/1440 场(最长连击 3);过旱按用户判读带集中在短命杂鱼(生存时长问题非池配置——见 06 清单 Alpha 条目移交注记) | +| 池 EV 锚 | 静态份额与含闸长期速率实测读数登记于调参日志(EV 重锚与权重投值随本表修订)。**2026-09-19 节奏体验验证批登记**(60 distinct seeds × 双策略 × 两关,tools/skill_rhythm_audit.py——20 种子以下批次有种子偏置假象,读数须 ≥50 种子):特殊技执行份额 对表成立——地精 10.4%(静态 10%)/ 地精一伙 8.4% / 熊地精系 28.9–42.4% / 巨蜘蛛 34.8% / 酋长 28.9% / 卓尔 35.4%;**L2 池含闸速率抽样复核完成**(上项即含闸读数);保底越界 0/247(间隔 4 = M=4 合法上界);过涝信号 8/1440 场(最长连击 3);过旱按用户判读带集中在短命杂鱼(生存时长问题非池配置——见待办清单清单 Alpha 条目移交注记) | 主角表与棋盘参数表(行值分别读 `hero.tres` 与 `board_gen.tres`,provisional): @@ -334,4 +334,4 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板 ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 diff --git a/design/gdd/systems/战斗循环/地图战斗资源.md b/design/gdd/systems/战斗循环/地图战斗资源.md index 68cb1d3e..a0c1443f 100644 --- a/design/gdd/systems/战斗循环/地图战斗资源.md +++ b/design/gdd/systems/战斗循环/地图战斗资源.md @@ -202,7 +202,7 @@ |---|---|---| | P1 | ~~功能道具渠道~~(已由秘宝体系承接——局外同调件:营地解锁 + 同调位装配,同调实施批 2026-10-03 落地;关卡节点渠道形态顺带退役) | 数值型伤害/治疗道具已删除(2026-09-15 用户定);本系统只留结构位不变 | | P1 | 清图池按图类型差异化 | 默认槽之外的结构位已留;词表现行三值({dungeon, underdark, deep_underdark}),差异化行随内容批配置 | -| P1 | 未开格资源类型的呈现深度 | 基础档已定——微光只读类型不读危险格与安全格(2026-10-07 案甲,实施归呈现批、06 在案);更深档与推理的界线另议 | +| P1 | 未开格资源类型的呈现深度 | 基础档已定——微光只读类型不读危险格与安全格(2026-10-07 案甲,实施归呈现批、待办清单在案);更深档与推理的界线另议 | | P1 | 增攻(attack)型行值与权重终调 | 内容决策,归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | | P2 | 音频挂钩(拾取音 / 负向兑付音 / 清图奖励音) | 归[音频](../表现与支撑/音频.md),Alpha | | P2 | 内容名录扩展(新资源行) | 机制与内容分离;现行行集收窄,扩展随内容批 | @@ -248,4 +248,4 @@ ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 diff --git a/design/gdd/systems/战斗循环/增益状态.md b/design/gdd/systems/战斗循环/增益状态.md index 8c6b8233..cdc83684 100644 --- a/design/gdd/systems/战斗循环/增益状态.md +++ b/design/gdd/systems/战斗循环/增益状态.md @@ -239,4 +239,4 @@ empower 与 fortify 是敌方技能池增益技在容器侧的数据落点(技 ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 diff --git a/design/gdd/systems/战斗循环/战斗结算.md b/design/gdd/systems/战斗循环/战斗结算.md index 50c60414..9e7c6faf 100644 --- a/design/gdd/systems/战斗循环/战斗结算.md +++ b/design/gdd/systems/战斗循环/战斗结算.md @@ -98,7 +98,7 @@ ### 收益对照表:所有收益共用同一把尺子 -开安全格给正向、封印标中给正向、踩雷与标错给负向、清图给清图奖励对象——来源不同、形态不同,但玩家必须能回答"挖这一格值不值",所以全部收益用一张效果档位对照表归一换算。折算单位是当量:1 当量等于 1 点主角生命的期望净变化。这张表是[行动经济](../排雷循环/行动经济.md)五条经济契约第一条"单一当量"的载体;本系统是全部五条契约的唯一对账责任方(契约本体见该文档,对账现状登记 [06-待办清单](../../06-待办清单.md))。 +开安全格给正向、封印标中给正向、踩雷与标错给负向、清图给清图奖励对象——来源不同、形态不同,但玩家必须能回答"挖这一格值不值",所以全部收益用一张效果档位对照表归一换算。折算单位是当量:1 当量等于 1 点主角生命的期望净变化。这张表是[行动经济](../排雷循环/行动经济.md)五条经济契约第一条"单一当量"的载体;本系统是全部五条契约的唯一对账责任方(契约本体见该文档,对账现状登记 [待办清单](../../../../待办清单.md))。 **结论**:单一线性换算全源共用,禁止分源改率;百分比效果按"每个结算的瞬时当量"口径折算。 @@ -212,7 +212,7 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × 主角攻击 = 单一基础分量(2026-09-19 充能退役批):量 = 攻击力基线(表值),类型 = 主角表 `attack_type`(营地永久强化换型 = 改字段;未来冒险前参数面承接"按关配型"的策略位)。原"普通 + 穿刺/魔法充能三分量"模型整体退役——挖掘期与战斗期之间不再有弹药供给线,克制应对从局内攒桶改为冒险前配型 + 棋盘火力(穿刺弹/魔法矢等直伤奖励道具,消费面不变)。 -**护甲等级掷点:必中、非归零,只吃基础攻击分量**(2026-09-16 定稿落地,判定式与全部数值已拍板;判定对象措辞随敌人技能池批改述)。防守方由此多了一条数值轴——护甲等级(数据键 `armor_class`):攻击永远命中,没有 miss、没有零收益白回合;只有吃掷点的分量在掷点低于防守方护甲等级时按减伤档位打折,档位再重也不归零。判定式:攻击结算时掷单骰(骰面读表),掷点 ≥ 防守方护甲等级 + 攻击加成 → 全额;掷点 < 护甲等级按缺口(护甲等级 − 掷点)查减伤档位表打折——边界与档值读 `settlement.tres` 减伤档位表,三档皆非零档。暴击:天然最大面(读表)使该次基础攻击分量 ×暴击倍率(读表),双方同规,且天然最大面恒全额(暴击与折扣互斥;天然最大面〔nat20〕暴击是掷点层概念,与技能重击〔池技能〕严格区分——两层禁止混述)。伤害下限:**任何来源的伤害落地**至少 damage_floor(读表,全局 max(damage_floor, ·)——2026-09-20 用户拍板扩全来源:攻击双方、棋盘直伤与爆裂、地形变异、负向反噬;伤害取值域 [1, +∞),**不设上限**)——"被减伤归零 v=0"零值伤害行语义顺带退役,重档折扣的攻击行在行文本记"被压制"。掷点范围:只有基础攻击分量吃掷点——主角先手攻击的基础分量,敌方技能的基础伤害分量(= 攻击基线 × 技能伤害倍率,普通攻击倍率 1 为特例);无伤害分量的技能(增益/妨害类)不掷不折;棋盘来源一律无视护甲等级——爆裂、清障炸药、奖励即时伤害、技能必中附加分量(rider,2026-09-19)全部必中全额不掷,这是本机制的边界切口,与"奖励/惩罚必中"同构。护甲等级(数值轴,掷点打折)与护甲类型(属性轴,克制修正)严格分离:护甲类型不做护甲等级映射,克制修正点数读表、消费面不变,两概念在文档、表字段与代码键中禁止混用。数值载体:主角与敌方护甲等级行值读 hero / enemy 表的 armor_class 列(正式行值归怪物设定批,登记[待办清单](../../06-待办清单.md)),ac_up(盾牌加护)在其上加算(幅度/层数读 `status_effects.tres`)。攻击加成(`attack_bonus`)为结构位预留字段,切片恒 0,未来归元进度 / 武器附魔投值。掷点时机在结算战斗段内、每次基础攻击伤害计算时判定,消费 `armor_roll` 封闭流(逐次掷逐次取号,可逐位回放)。 +**护甲等级掷点:必中、非归零,只吃基础攻击分量**(2026-09-16 定稿落地,判定式与全部数值已拍板;判定对象措辞随敌人技能池批改述)。防守方由此多了一条数值轴——护甲等级(数据键 `armor_class`):攻击永远命中,没有 miss、没有零收益白回合;只有吃掷点的分量在掷点低于防守方护甲等级时按减伤档位打折,档位再重也不归零。判定式:攻击结算时掷单骰(骰面读表),掷点 ≥ 防守方护甲等级 + 攻击加成 → 全额;掷点 < 护甲等级按缺口(护甲等级 − 掷点)查减伤档位表打折——边界与档值读 `settlement.tres` 减伤档位表,三档皆非零档。暴击:天然最大面(读表)使该次基础攻击分量 ×暴击倍率(读表),双方同规,且天然最大面恒全额(暴击与折扣互斥;天然最大面〔nat20〕暴击是掷点层概念,与技能重击〔池技能〕严格区分——两层禁止混述)。伤害下限:**任何来源的伤害落地**至少 damage_floor(读表,全局 max(damage_floor, ·)——2026-09-20 用户拍板扩全来源:攻击双方、棋盘直伤与爆裂、地形变异、负向反噬;伤害取值域 [1, +∞),**不设上限**)——"被减伤归零 v=0"零值伤害行语义顺带退役,重档折扣的攻击行在行文本记"被压制"。掷点范围:只有基础攻击分量吃掷点——主角先手攻击的基础分量,敌方技能的基础伤害分量(= 攻击基线 × 技能伤害倍率,普通攻击倍率 1 为特例);无伤害分量的技能(增益/妨害类)不掷不折;棋盘来源一律无视护甲等级——爆裂、清障炸药、奖励即时伤害、技能必中附加分量(rider,2026-09-19)全部必中全额不掷,这是本机制的边界切口,与"奖励/惩罚必中"同构。护甲等级(数值轴,掷点打折)与护甲类型(属性轴,克制修正)严格分离:护甲类型不做护甲等级映射,克制修正点数读表、消费面不变,两概念在文档、表字段与代码键中禁止混用。数值载体:主角与敌方护甲等级行值读 hero / enemy 表的 armor_class 列(正式行值归怪物设定批,登记[待办清单](../../../../待办清单.md)),ac_up(盾牌加护)在其上加算(幅度/层数读 `status_effects.tres`)。攻击加成(`attack_bonus`)为结构位预留字段,切片恒 0,未来归元进度 / 武器附魔投值。掷点时机在结算战斗段内、每次基础攻击伤害计算时判定,消费 `armor_roll` 封闭流(逐次掷逐次取号,可逐位回放)。 EV 参考数不入正文(派生读数,需要时按判定式与现行表值自行复算);旧 defense_up 的减伤墙已整体退役换装为 AC(无双轨)。微调旋钮 = 档位边界与档位值,不动护甲等级值。换装点锚定:基准 AC(读 hero 表)自带的方向性偏移与[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)已登记的加难杠杆扫描合并处理;其生存链区间模型按掷点带宽口径复核 @@ -278,7 +278,7 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值 | 上游 | [冒险结构](../冒险循环/冒险结构.md) | 战斗触发、遭遇上下文与主角入参覆盖值(覆盖值通道已随冒险结构实现批正式接线——接口四件套正式侧承载) | | 下游 | [HUD 框架](../表现与支撑/HUD框架.md) | 明细流水是结算明细屏的统一数据源(未生效类行须带形状冗余防误读);状态读取走下方呈现只读面 | | 下游 | [战斗表现](战斗表现.md) | 结算步骤流是战斗动画回放的脚本源 | -| 下游 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | 五条经济契约的对账结论是其调参约束输入(对账现状登记 [06-待办清单](../../06-待办清单.md)) | +| 下游 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | 五条经济契约的对账结论是其调参约束输入(对账现状登记 [待办清单](../../../../待办清单.md)) | ### 呈现只读面:呈现层的唯一状态读取出口 @@ -356,4 +356,4 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值 ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 diff --git a/design/gdd/systems/战斗循环/战斗表现.md b/design/gdd/systems/战斗循环/战斗表现.md index 0fac1db6..7ae83c6c 100644 --- a/design/gdd/systems/战斗循环/战斗表现.md +++ b/design/gdd/systems/战斗循环/战斗表现.md @@ -74,13 +74,13 @@ 附着在同一次样张上的还有一项已登记的裁决(登记出处 = 敌人系统的呈现契约):敌人层绘制优先级的插入位置——白话就是敌人的姿态精灵画在绘制顺序的哪一层,会不会、以及如何与棋盘上的数字、封印印记、小人发生遮挡。它随美术测试一并裁决,不在本文提前定。 -两项相邻裁定已有结论,设计时直接继承:**敌人呈现形态已裁决(2026-09-20 用户看对照样张拍板)——全站桩式(无框立绘+底座),主角同样站桩、状态小图标挂血条正下方,卡片式整体退役**(06 待办「敌人卡形态」解决移除,状态记录 99;battle.md 起草条款已随裁决改写,对照样张存档 `production/mockups/`);art-bible 的图标键契约已冻结,动画设计不必等图标终稿。 +两项相邻裁定已有结论,设计时直接继承:**敌人呈现形态已裁决(2026-09-20 用户看对照样张拍板)——全站桩式(无框立绘+底座),主角同样站桩、状态小图标挂血条正下方,卡片式整体退役**(待办清单「敌人卡形态」解决移除,状态记录 99;battle.md 起草条款已随裁决改写,对照样张存档 `production/mockups/`);art-bible 的图标键契约已冻结,动画设计不必等图标终稿。 ### 一屏样张的验收标准 样张是前置美术测试的判定物;本节把"怎么算过"在测试组织前写成文,避免临场现定标准。成文做法参照 [art-bible](../../../art/art-bible.md) §1.4 格子样张测试(内容清单、按序验收项、判定与回退),判据全部落到已冻结的现行口径上——本节不定任何新的视觉参数。 -样张内容清单(一组齐备,缺项即无效):按 [battle.md 布局决策 1](../../ux/battle.md) 的常驻双舞台四区布局整屏出样;角色剪影按棋盘格、结算明细带、战斗舞台三个语境同图摆放;~~敌人卡两候选形态对照(卡片式与站桩式各一版,其余内容不变)~~——**本项已由 2026-09-20 形态裁决提前完成(全站桩定稿、卡片式退役),正式样张按站桩形态单版出样即可**(owner 修订,对照义务解除;见 06 待办「敌人卡形态」销项,状态记录 99);受击、退场、高光兑现三组动画关键帧条(每组至少起、中、末三帧);敌人姿态精灵与数字、封印印记、小人同格叠放的遮挡对照组至少一组。 +样张内容清单(一组齐备,缺项即无效):按 [battle.md 布局决策 1](../../ux/battle.md) 的常驻双舞台四区布局整屏出样;角色剪影按棋盘格、结算明细带、战斗舞台三个语境同图摆放;~~敌人卡两候选形态对照(卡片式与站桩式各一版,其余内容不变)~~——**本项已由 2026-09-20 形态裁决提前完成(全站桩定稿、卡片式退役),正式样张按站桩形态单版出样即可**(owner 修订,对照义务解除;见待办清单「敌人卡形态」销项,状态记录 99);受击、退场、高光兑现三组动画关键帧条(每组至少起、中、末三帧);敌人姿态精灵与数字、封印印记、小人同格叠放的遮挡对照组至少一组。 验收项按序判定,第一项不过 = 整张否决(继承格子样张"数字可读性定风格"的次序): @@ -150,7 +150,7 @@ MVP 不要求本文的闭环:不做清单把战斗动画演出列为 MVP 打 ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 ## 待设计问题清单 diff --git a/design/gdd/systems/战斗循环/敌人系统.md b/design/gdd/systems/战斗循环/敌人系统.md index f56c403c..61ee71bf 100644 --- a/design/gdd/systems/战斗循环/敌人系统.md +++ b/design/gdd/systems/战斗循环/敌人系统.md @@ -91,7 +91,7 @@ | 钩爪恐魔 | 普通攻击 + 撕咬 + 蓄力 | 行值读表 | 行值读表 | L2/L3 群行位(蜘蛛同构池) | | 灰矮人石君王 | 普通攻击 + 重击 + 大地脉动 + **岩崩**(半血解锁) | 行值读表 | 行值读表 | L3 关底 Boss;大地脉动独占 | -护甲类型(轻甲 / 魔法护甲 / 重甲)与攻击类型的克制结算矩阵归[战斗结算](战斗结算.md),本系统只提供每个敌种的护甲类型数据——**护甲列自 2026-10-05 技能池执行批起改读表口径**(本表轮廓列不再记具体甲型:现行 L1 全轻甲 / L2 仅 Boss 魔法甲 / L3 heavy 登台的错峰投放以 `enemy.tres` 行值为准;历史「本表写魔甲/重甲」与表失同步的欠账顺带清偿)。护甲等级是另一条数值轴(防守方字段,基础攻击掷点的折扣判定读数):敌人表与主角表各增 `armor_class` 一列(域 [0, 999]),掷点与折扣的结算归[战斗结算](战斗结算.md),行值投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)——三敌种首关与主角的护甲等级行值读配置表(第一关怪物 AC 相对较低,正式行值待怪物设定投值,登记[待办清单](../../06-待办清单.md)),两条轴的概念与字段禁止混用。举证:生成与护甲为数据面规则,无计算。 +护甲类型(轻甲 / 魔法护甲 / 重甲)与攻击类型的克制结算矩阵归[战斗结算](战斗结算.md),本系统只提供每个敌种的护甲类型数据——**护甲列自 2026-10-05 技能池执行批起改读表口径**(本表轮廓列不再记具体甲型:现行 L1 全轻甲 / L2 仅 Boss 魔法甲 / L3 heavy 登台的错峰投放以 `enemy.tres` 行值为准;历史「本表写魔甲/重甲」与表失同步的欠账顺带清偿)。护甲等级是另一条数值轴(防守方字段,基础攻击掷点的折扣判定读数):敌人表与主角表各增 `armor_class` 一列(域 [0, 999]),掷点与折扣的结算归[战斗结算](战斗结算.md),行值投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)——三敌种首关与主角的护甲等级行值读配置表(第一关怪物 AC 相对较低,正式行值待怪物设定投值,登记[待办清单](../../../../待办清单.md)),两条轴的概念与字段禁止混用。举证:生成与护甲为数据面规则,无计算。 ### 技能池:每敌种一张带权技能池,每拍开轮摇号出招 @@ -213,13 +213,13 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(**技能错 | 优先级 | 内容 | 后置原因 | |---|---|---| -| P1 | 情境条件触发器(低血触发防御、玩家停手时偷袭技等) | 载体 = 技能行触发条件字段加列;登记[待办清单](../../06-待办清单.md) | -| P1 | 个体化变体池(A 型好斗 / B 型守势、精英专属池) | 共识点 A 的 A2 案;登记[待办清单](../../06-待办清单.md) | -| P1 | 全局特殊间隔旋钮 | 特殊技背靠背实测仍嫌时的备用闸;登记[待办清单](../../06-待办清单.md) | -| P1 | 新效应词汇批(妨害技 + 必中附加分量已实装 2026-09-19——设计权威 proposal-status-vocabulary.md〔提案已吸收退役 git a6833b6a——现行事实源=敌人系统.md 词汇表/增益状态.md〕 v1.0,实装面 = L2 Boss 卓尔;多段命中经用户拍板退役) | 妨害类型 + rider_mult 字段已落地;登记[待办清单](../../06-待办清单.md)(已解决移除,去向见状态记录) | +| P1 | 情境条件触发器(低血触发防御、玩家停手时偷袭技等) | 载体 = 技能行触发条件字段加列;登记[待办清单](../../../../待办清单.md) | +| P1 | 个体化变体池(A 型好斗 / B 型守势、精英专属池) | 共识点 A 的 A2 案;登记[待办清单](../../../../待办清单.md) | +| P1 | 全局特殊间隔旋钮 | 特殊技背靠背实测仍嫌时的备用闸;登记[待办清单](../../../../待办清单.md) | +| P1 | 新效应词汇批(妨害技 + 必中附加分量已实装 2026-09-19——设计权威 proposal-status-vocabulary.md〔提案已吸收退役 git a6833b6a——现行事实源=敌人系统.md 词汇表/增益状态.md〕 v1.0,实装面 = L2 Boss 卓尔;多段命中经用户拍板退役) | 妨害类型 + rider_mult 字段已落地;登记[待办清单](../../../../待办清单.md)(已解决移除,去向见状态记录) | | P1 | 敌种名录扩容与投放节奏(含第二关池与投放) | 投放节奏是关卡命脉,归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | | P1 | 单体寻址("只打某一个敌人"的目标指定) | 首个单体效果上线时顺带裁决归集语义与呈现 | -| P2 | 敌方技能图鉴 / 学习呈现(玩家侧技能知识系统) | 池不公开口径下的进阶信息面;登记[待办清单](../../06-待办清单.md) | +| P2 | 敌方技能图鉴 / 学习呈现(玩家侧技能知识系统) | 池不公开口径下的进阶信息面;登记[待办清单](../../../../待办清单.md) | | P2 | ~~精英 / Boss 遭遇编码位~~(已完成——不设编码位:同层多遭遇由节点编号消解,关卡节点地图 v1.0⑥ 用户裁决) | — | ## 调参表 @@ -262,7 +262,7 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(**技能错 各敌种行值、池权重与池 EV 读数(含闸长期速率实测)一律读配置表与调参日志,本文不登记具体数值;EV 重锚与权重投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)。 -结构冻结(非调参项,修订走本文流程):技能类型枚举封闭、每池恰一普攻、每池增益 ≤1、死亡即不动手(摇定后兑现前死亡作废不进账)、每结算每存活敌恰行动一次、行序、先作用后推进、固定顺位、**行集构成纪律(2026-10-07 行集多行批换代——原「每坐标恰一敌种」退役:行集内 enemy_id 唯一 + 同坐标多行文件内相邻且行序 = 声明序 = 生成序 + 行集实例总数 ≤ 4)**、零随机(本系统自身语义零随机不变——摇号与掷点随机一律在[战斗结算](战斗结算.md)结算换算层按封闭随机流掷定,可回放契约 = 同种子同输入逐位复现,单敌出招轨迹可独立复放)。联动纪律:技能倍率 × 攻击(伤害拍支配)、权重 × 冷却 × 保底(池节奏三联动)禁止独立调参,联调须重跑方向性预检并同步 registry(登记 [06-待办清单](../../06-待办清单.md))。 +结构冻结(非调参项,修订走本文流程):技能类型枚举封闭、每池恰一普攻、每池增益 ≤1、死亡即不动手(摇定后兑现前死亡作废不进账)、每结算每存活敌恰行动一次、行序、先作用后推进、固定顺位、**行集构成纪律(2026-10-07 行集多行批换代——原「每坐标恰一敌种」退役:行集内 enemy_id 唯一 + 同坐标多行文件内相邻且行序 = 声明序 = 生成序 + 行集实例总数 ≤ 4)**、零随机(本系统自身语义零随机不变——摇号与掷点随机一律在[战斗结算](战斗结算.md)结算换算层按封闭随机流掷定,可回放契约 = 同种子同输入逐位复现,单敌出招轨迹可独立复放)。联动纪律:技能倍率 × 攻击(伤害拍支配)、权重 × 冷却 × 保底(池节奏三联动)禁止独立调参,联调须重跑方向性预检并同步 registry(登记 [待办清单](../../../../待办清单.md))。 ## 验收标准 @@ -281,4 +281,4 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(**技能错 ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 diff --git a/design/gdd/systems/排雷循环/排雷玩法.md b/design/gdd/systems/排雷循环/排雷玩法.md index d4500571..4aef8b2d 100644 --- a/design/gdd/systems/排雷循环/排雷玩法.md +++ b/design/gdd/systems/排雷循环/排雷玩法.md @@ -239,4 +239,4 @@ ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 diff --git a/design/gdd/systems/排雷循环/行动经济.md b/design/gdd/systems/排雷循环/行动经济.md index 79836f41..b49356d2 100644 --- a/design/gdd/systems/排雷循环/行动经济.md +++ b/design/gdd/systems/排雷循环/行动经济.md @@ -257,4 +257,4 @@ ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 diff --git a/design/gdd/systems/表现与支撑/HUD框架.md b/design/gdd/systems/表现与支撑/HUD框架.md index 2d2cd3af..8ce77653 100644 --- a/design/gdd/systems/表现与支撑/HUD框架.md +++ b/design/gdd/systems/表现与支撑/HUD框架.md @@ -137,11 +137,11 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻 | 信息内容 | 只表达格面资源的类型(九类格面资源归五组色相呈现,色相/明度/画法规格归 [art-bible](../../../art/art-bible.md) §4.2);不表达极性(安全/雷)、不表达具体收益档位 | | 生命周期 | 资源身份装板期摇定(微光只是显示,不改任何游戏数据)→ 未开 ∧ 在 8 格内 → 亮;格子被挖开/连锁开/踩雷 → 灭;角色走远出圈 → 灭,走回 → 复亮;换图随旧图全重置 | | 关联与边界 | 信息本体(格面资源身份)归[地图战斗资源](../战斗循环/地图战斗资源.md);棋盘格态与动作合法性归[排雷玩法](../排雷循环/排雷玩法.md);与「接触带微光」同圈不同职责——接触带微光=可挖域的交互反馈光(「这里能挖」),类型微光=相邻格的类型先读(「这格是什么类型」) | -| 实装状态 | 呈现契约已定稿(五组色相经样张 v2 冻结 2026-09-28);**已实装(迭代 30 卡① 2026-10-17 入库,合并 `7ffd1dc0`)**——2026-09-30 核证的「呈现层仅接触带微光在跑,类型微光无独立实现」状态自此注销;在役实现(五组色相 = ui_kit TG_GLOW_*、格面微光子件 + 距离场 shader)与验收转正见本节末「验收标准」类型微光行,登记面归 [06-待办清单](../../06-待办清单.md)「未开格类型徽章呈现时机」条(已完成) | +| 实装状态 | 呈现契约已定稿(五组色相经样张 v2 冻结 2026-09-28);**已实装(迭代 30 卡① 2026-10-17 入库,合并 `7ffd1dc0`)**——2026-09-30 核证的「呈现层仅接触带微光在跑,类型微光无独立实现」状态自此注销;在役实现(五组色相 = ui_kit TG_GLOW_*、格面微光子件 + 距离场 shader)与验收转正见本节末「验收标准」类型微光行,登记面归 [待办清单](../../../../待办清单.md)「未开格类型徽章呈现时机」条(已完成) | -口径史注记(防复发):本概念曾只活在 06-待办清单登记与 art-bible 复述里,「常显」「全部未开格」等无范围表述于 2026-09-30 酿成理解事故;用户裁决「英雄周围 8 格」为正确口径并落位本节。教训=概念必须落地权威文档,零散复述不是定义。 +口径史注记(防复发):本概念曾只活在待办清单登记与 art-bible 复述里,「常显」「全部未开格」等无范围表述于 2026-09-30 酿成理解事故;用户裁决「英雄周围 8 格」为正确口径并落位本节。教训=概念必须落地权威文档,零散复述不是定义。 -两带分工注记(2026-10-17 迭代 30 卡①登记):类型微光实装后,棋盘外另有「卡顶色带」(徽章/条目顶边色带,悬赏与秘宝等面板格面条目顶边的类型色带)与本格面微光并存——卡顶带 = 条目级静态色带(一眼扫类型),格面微光 = 棋盘格内动态微光(相邻先读);两套载体不同、职责不同,**禁互为引用**。两带统一面(卡顶带取值改用 art-bible 五组色值、归组改 cell_type 精确值)归 [06-待办清单](../../06-待办清单.md)「卡顶色带与格面微光两带统一」条(待办)。 +两带分工注记(2026-10-17 迭代 30 卡①登记):类型微光实装后,棋盘外另有「卡顶色带」(徽章/条目顶边色带,悬赏与秘宝等面板格面条目顶边的类型色带)与本格面微光并存——卡顶带 = 条目级静态色带(一眼扫类型),格面微光 = 棋盘格内动态微光(相邻先读);两套载体不同、职责不同,**禁互为引用**。两带统一面(卡顶带取值改用 art-bible 五组色值、归组改 cell_type 精确值)归 [待办清单](../../../../待办清单.md)「卡顶色带与格面微光两带统一」条(待办)。 ### 可挖域指示(接触带微光):「这里能挖」的交互反馈光 @@ -166,7 +166,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻 | 关联与边界 | 与「未开格类型微光」同边界——灯光区起步半径=微光环 8 格(同圈起步,实测后可调);格态数据归[排雷玩法](../排雷循环/排雷玩法.md);黑暗区域渲染规格(暗淡态明度、迷雾过渡)归 [art-bible](../../../art/art-bible.md) 修订随实施批;初始展开收窄不在本案(后置与 Alpha 差异化批窗口合并再议) | | 实装状态 | **已实装**(2026-10-03 迭代 11 第④批已入库;四裁决逐条对账与验收线转正见本节末「实施状态」注记;渲染规格 = [art-bible](../../../art/art-bible.md) §6.5) | -配套拍板(同日):魔法提灯=灯甲形态(光照圈外扩 +2 格,flat 整数档)随迷雾立项;**类型微光不随视野扩大**(类型先读仍只贴身 8 格,微光锚=可挖域);提灯载体归 aux_items 新行(登记原文——2026-10-07 用户令改道为独立卡,2026-10-08 裁案A=秘宝·同调位新行落位,见下方实施状态注记;**2026-10-09 用户裁退役**——新目录 15 件未收提灯,fog_lantern 数据行与卡④接线拆除归退役删行批〔实装批〕,功能由新目录普通档「阔视野带」承接,06 登记条在册),呈现面挂「资产升档重产批」(挂账不动)。 +配套拍板(同日):魔法提灯=灯甲形态(光照圈外扩 +2 格,flat 整数档)随迷雾立项;**类型微光不随视野扩大**(类型先读仍只贴身 8 格,微光锚=可挖域);提灯载体归 aux_items 新行(登记原文——2026-10-07 用户令改道为独立卡,2026-10-08 裁案A=秘宝·同调位新行落位,见下方实施状态注记;**2026-10-09 用户裁退役**——新目录 15 件未收提灯,fog_lantern 数据行与卡④接线拆除归退役删行批〔实装批〕,功能由新目录普通档「阔视野带」承接,待办清单登记条在册),呈现面挂「资产升档重产批」(挂账不动)。 **实施状态(2026-10-03 迭代 11 第④批已入库)**:迷雾遮蔽+菱形灯光区跟随+暗淡记忆态上线,探针断言顺带扩(ui_input_probe case⑮)。四裁决逐条对账——①案甲视野迷雾立项(纯呈现层):迷雾开关分层验证可用(呈现态布尔,off 态=无迷雾基线),同板同动作序列与 MC 逐项比对逐位一致;②暗淡记忆态:区外已开格灰显+数字可读,明度按 [art-bible](../../../art/art-bible.md) §6.5 写入文档值(记忆板 #3A3A3A/记忆墨 #C4C4C4,provisional);③灯光半径=微光环 8 格同圈:LIGHT_RADIUS=8 参数化(曼哈顿菱形,常量);④提灯 +2、微光不扩:FOG_LANTERN_BONUS=+2(落码常量实名——本条旧记 LIGHT_RADIUS_LANTERN_BONUS 系文档侧拟名,随卡④入库对齐),类型微光仍贴身 8 邻格零改动。**〔2026-10-05 迭代14⑤接线注记〕公共接线面已就位**——`board_view.set_fog_lantern(enabled)`(true=半径 8+2、false=复原 0;写入即 refresh 重算雾态),半径算式消费 `_fog_lantern` 迷雾批已在位;ui_input_probe case⑮ 增接线断言(开=dist 9 格转可见+lantern=2/关=复原)。**〔2026-10-08 迭代 19 卡④入库注记〕载体到位+接线闭环=功能可达**——载体=秘宝·同调位新行 `fog_lantern`「魔法提灯」(treasure_items.tres 表尾追加,desc「灯光区半径+2」,slot_cost 1、营地秘宝匣同调装配获渠,行字段=用户「按推荐」全收);生产路径=runner set_attunement→enc.attunement→begin_battle 注入 orchestrator 装配集→公共只读出口 `attune_has`→组合根呈现桥 `main._sync_fog_lantern` 每战首轮装配链**显式重算含否**(🔴 复原语义=禁战斗结束隐式复原——卸装/未装配写 0,断点续玩/跨关天然正确);未装配=false 写 0=缺省零扰动基线逐位不变。顺带测试:case⑮ 载体级段(装配→lantern=2+dist R+1 转可见+卸装复原)+smoke 行字段/同调目录投影(九件→十件)/装配贯通断言+存档回归 Part 6+单测 fog_lantern_wiring(run_all 17→18 套)。原「提灯载体归 aux_items 新行随 Alpha 信息件重定批」登记去向就此注销(改道留痕=需求卡片-提灯载体道具批-2026-10-07 §一)。验收线(本篇「验收标准」视野迷雾行)逐条转正式验收:区内完整渲染/区外已开格灰显可读/区外未开格不可见/灯光区随移动跟随/两态结算逐位一致;实机目检人闸(迷雾观感/记忆态可读性/移动跟随流畅度)随出口闸。黑暗区域渲染规格承载 = art-bible §6.5(v3.5)。 @@ -287,4 +287,4 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻 ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 diff --git a/design/gdd/systems/表现与支撑/存档序列化.md b/design/gdd/systems/表现与支撑/存档序列化.md index de4ff699..2845fdbf 100644 --- a/design/gdd/systems/表现与支撑/存档序列化.md +++ b/design/gdd/systems/表现与支撑/存档序列化.md @@ -180,4 +180,4 @@ MVP 不要求本系统的闭环([不做清单](../../05-不做清单.md)把单 ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 diff --git a/design/gdd/systems/表现与支撑/教学引导.md b/design/gdd/systems/表现与支撑/教学引导.md index 88b81957..7bc9828f 100644 --- a/design/gdd/systems/表现与支撑/教学引导.md +++ b/design/gdd/systems/表现与支撑/教学引导.md @@ -64,7 +64,7 @@ HUD 框架定稿时已为教学留好两个承载位,本系统的内容将来 ### 内容原则 -- **整体后置**:教学引导是 MVP 之后的打磨项(见 [不做清单](../../05-不做清单.md):先验证核心循环,再谈好听好看);改排 **Beta 阶段**(2026-10-04 用户拍板——当前 Alpha 版不做教学相关工作,登记见 [06-待办清单](../../06-待办清单.md)教学引导节头注记)。 +- **整体后置**:教学引导是 MVP 之后的打磨项(见 [不做清单](../../05-不做清单.md):先验证核心循环,再谈好听好看);改排 **Beta 阶段**(2026-10-04 用户拍板——当前 Alpha 版不做教学相关工作,登记见 [待办清单](../../../../待办清单.md)教学引导节头注记)。 - **一次性提示**:首次触发类提示每场冒险至多出现一次,不反复轰炸。 - **只教规则,不替玩家玩**:教学解释规则与因果,不提供自动操作或"最优解"提示。 diff --git a/design/gdd/systems/表现与支撑/数据配置.md b/design/gdd/systems/表现与支撑/数据配置.md index d9586baa..13ba1788 100644 --- a/design/gdd/systems/表现与支撑/数据配置.md +++ b/design/gdd/systems/表现与支撑/数据配置.md @@ -209,4 +209,4 @@ ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 diff --git a/design/gdd/systems/表现与支撑/设置与本地化.md b/design/gdd/systems/表现与支撑/设置与本地化.md index 407dcbc5..5dd21cf5 100644 --- a/design/gdd/systems/表现与支撑/设置与本地化.md +++ b/design/gdd/systems/表现与支撑/设置与本地化.md @@ -112,7 +112,7 @@ MVP 不要求本系统的闭环:[不做清单](../../05-不做清单.md)把设 ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 ## 待设计问题清单 diff --git a/design/gdd/systems/表现与支撑/音频.md b/design/gdd/systems/表现与支撑/音频.md index f1df7227..769b38f4 100644 --- a/design/gdd/systems/表现与支撑/音频.md +++ b/design/gdd/systems/表现与支撑/音频.md @@ -142,7 +142,7 @@ ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 ## 待设计问题清单 diff --git a/design/gdd/systems/跨局循环/元进度.md b/design/gdd/systems/跨局循环/元进度.md index 5a12d47b..68f14233 100644 --- a/design/gdd/systems/跨局循环/元进度.md +++ b/design/gdd/systems/跨局循环/元进度.md @@ -103,7 +103,7 @@ ### 解锁界面:双入口框架 -(2026-09-18 拍板)主菜单设营地独立入口(消费钥石、查看与管理永久强化);局内状态面板(原称暂停层,2026-10-13 改名——游戏非实时无暂停语义)也可查看钥石余额与已解锁清单(只读)。钥石余额在 HUD 常驻展示。呈现 spec 已出生:[ux/camp.md](../../ux/camp.md) v1.0(2026-09-30 审计拍板点 4A 裁决写入文档——退役/封存件「已退役/已解锁·能力封存中」呈现语义随 spec 落位);视觉终稿已随迭代 9 9A 段落码(2026-09-30)。本节锁框架与需求,呈现细节归 spec;局内状态面板入口已实装(2026-10-06 迭代 17 卡③〔时名暂停层〕——实机目检待用户,06 登记条在册)。 +(2026-09-18 拍板)主菜单设营地独立入口(消费钥石、查看与管理永久强化);局内状态面板(原称暂停层,2026-10-13 改名——游戏非实时无暂停语义)也可查看钥石余额与已解锁清单(只读)。钥石余额在 HUD 常驻展示。呈现 spec 已出生:[ux/camp.md](../../ux/camp.md) v1.0(2026-09-30 审计拍板点 4A 裁决写入文档——退役/封存件「已退役/已解锁·能力封存中」呈现语义随 spec 落位);视觉终稿已随迭代 9 9A 段落码(2026-09-30)。本节锁框架与需求,呈现细节归 spec;局内状态面板入口已实装(2026-10-06 迭代 17 卡③〔时名暂停层〕——实机目检待用户,待办清单登记条在册)。 ### 单局循环零依赖:排期边界的推论 @@ -156,4 +156,4 @@ MVP 不要求本系统的闭环([不做清单](../../05-不做清单.md)整体 ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 diff --git a/design/gdd/systems/跨局循环/天赋树.md b/design/gdd/systems/跨局循环/天赋树.md index 8fcf9286..5be6795e 100644 --- a/design/gdd/systems/跨局循环/天赋树.md +++ b/design/gdd/systems/跨局循环/天赋树.md @@ -54,7 +54,7 @@ - **生命/命中淬炼唯一入口**——生命/命中的永久强化只在树脊柱淬炼节点购买;攻/AC 的永久强化唯一入口=锻造工坊武器/护甲路线(所有权切分,2026-10-11 裁——树零攻防来源=红线)。旧属性锻造柜台(forge_levels 三档直购)退役:生命档吸收进脊柱、攻/护档由[锻造工坊](锻造工坊.md)实装批路线化改造承接,`forge_levels` 旧存档域随实装批清退(开发阶段无迁移——旧档破坏性废弃,见存档域节)。 - **工作间钥匙模型**——锻造工坊、秘宝匣是树上两枚免费解锁节点(钥匙):点亮后展开对应工作间柜台面板,工作间内的升级操作(武器/护甲路线升级、秘宝解锁与同调装配)不在树上重复成节点。钥匙节点本身零币、不可跳过——锻造工坊钥匙无前置、直接可点亮(2026-10-11 裁),秘宝匣钥匙前置=脊柱生命第 1 级;钥匙未点亮时对应柜台锁定态,没点亮就进不去工作间。 - **图鉴常开**——奖励格图鉴是查看类功能,不设钥匙、不设门槛。 -- 实装前过渡态:旧柜台三档直购维持现役(与树淬炼在注入面叠加),退役动作随 06「天赋树实装批」执行。 +- 实装前过渡态:旧柜台三档直购维持现役(与树淬炼在注入面叠加),退役动作随待办清单「天赋树实装批」执行。 ### 一脊三脉:节点构成 @@ -157,7 +157,7 @@ A/B 态只放规则面:节点行持 a/b 双效果键(封闭规则键词表 R ## P0 最小闭环 -**P0 语义已随迭代 21 全量落地(2026-10-12 入库;2026-10-13 反哺写入换代——原「33 节点现役态维持」过渡态终结)**:12 节点结构(脊柱 = 生命/命中一线一节点、Fork = 三节点双态)+ 营地统一(树 = 营地本体、生命/命中唯一入口、攻防归锻造工坊、工作间钥匙、四柜台呈现)+ 三组 Fork 双态真效果 + 购买/切换/门槛/彩蛋/注入/旧档废弃全链,机检 = 冒烟 886/0 + run_all 22 套 + probe 全绿 + MC 三组配对差 0.0pp(迭代 21 出口闸读数);残留人闸 = 实机目检营地四柜台(07 ⑳)。旧 33 节点结构随 `TREE_STRUCT_VERSION=2` 废弃重置(禁迁移,Q3 裁)。 +**P0 语义已随迭代 21 全量落地(2026-10-12 入库;2026-10-13 反哺写入换代——原「33 节点现役态维持」过渡态终结)**:12 节点结构(脊柱 = 生命/命中一线一节点、Fork = 三节点双态)+ 营地统一(树 = 营地本体、生命/命中唯一入口、攻防归锻造工坊、工作间钥匙、四柜台呈现)+ 三组 Fork 双态真效果 + 购买/切换/门槛/彩蛋/注入/旧档废弃全链,机检 = 冒烟 886/0 + run_all 22 套 + probe 全绿 + MC 三组配对差 0.0pp(迭代 21 出口闸读数);残留人闸 = 实机目检营地四柜台(体验验证清单 ⑳)。旧 33 节点结构随 `TREE_STRUCT_VERSION=2` 废弃重置(禁迁移,Q3 裁)。 ## P1 / P2 后置 @@ -166,7 +166,7 @@ A/B 态只放规则面:节点行持 a/b 双效果键(封闭规则键词表 R | P1 | 命中线 flat 入注入面 | 消费面 = 命中折扣档归数值批(代码批注在册) | | P2 | 彩蛋发现率监控 | 发现率过低改树内灰色预告的反例条件在册;监控读数归呈报线 | -(原 P1「Fork 效果面差异化」已定案归实装批;「同调位 / 刷新升级消费面接管」已定案归实装批〔刷新升级定性缺陷修复〕;「三柜台→一树」已由营地统一模型〔案甲〕承接——三者均并入 06「天赋树实装批」,不再单列。) +(原 P1「Fork 效果面差异化」已定案归实装批;「同调位 / 刷新升级消费面接管」已定案归实装批〔刷新升级定性缺陷修复〕;「三柜台→一树」已由营地统一模型〔案甲〕承接——三者均并入待办清单「天赋树实装批」,不再单列。) ## 调参表 @@ -181,7 +181,7 @@ A/B 态只放规则面:节点行持 a/b 双效果键(封闭规则键词表 R ## 验收标准 -> **落地实态(2026-10-13 反哺写入注)**:下列各条已随迭代 21 实装并过出口闸——机检 = 冒烟 886/0(V1-V10/V16 断言顺带)+ run_all 22 套(tree_rules_v11_test 六键闭集)+ probe --click/--full 八探针 + render_gate + MC 三组同种子配对差 0.0pp(V19);残留人闸 = 实机目检营地四柜台(07 ⑳)。命中线「暂不注入」括注 = 契约 6 纪律维持(非缺陷——消费面开启归数值批)。 +> **落地实态(2026-10-13 反哺写入注)**:下列各条已随迭代 21 实装并过出口闸——机检 = 冒烟 886/0(V1-V10/V16 断言顺带)+ run_all 22 套(tree_rules_v11_test 六键闭集)+ probe --click/--full 八探针 + render_gate + MC 三组同种子配对差 0.0pp(V19);残留人闸 = 实机目检营地四柜台(体验验证清单 ⑳)。命中线「暂不注入」括注 = 契约 6 纪律维持(非缺陷——消费面开启归数值批)。 - 结构封闭:meta_tree.tres 通过 schema 校验零违例——12 节点、脉 / 类型 / 币词表出域即拒、Fork 三组每组恰一节点且持 a/b 双效果键、彩蛋 ≤3、effects 键封闭、零 archetype 键。 - 行门槛可判:全树已购总等级 < 4×(N−1) 时脊柱节点第 N 级不可购;总等级达标当刻该级开放购买。 @@ -195,4 +195,4 @@ A/B 态只放规则面:节点行持 a/b 双效果键(封闭规则键词表 R ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md)「天赋树实装批」条,本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md)「天赋树实装批」条,本节不再逐条登记。 diff --git a/design/gdd/systems/跨局循环/生涯.md b/design/gdd/systems/跨局循环/生涯.md index c8ba53cc..cf95cfeb 100644 --- a/design/gdd/systems/跨局循环/生涯.md +++ b/design/gdd/systems/跨局循环/生涯.md @@ -2,7 +2,7 @@ > **一句话定位**:主菜单里与营地平级的**局外只读界面**——营地管「花」(花钥石买永久强化),生涯管「看」(看自己跨局攒下的一切:累计战绩、历史冒险、图鉴收集)。冒险进行中不给任何数据回看(2026-10-04 用户裁决 P-C7 的延续),生涯是历史数据唯一的家。 > **状态**:期一已实装(2026-10-07 迭代 18 卡④生涯界面实装批·期一——跨局汇总页+主菜单入口+终身计数域存档 v6 落地;期二/期三另行立项,本文不预占排期)。 -> **来源**:[06-待办清单「『生涯』界面——冒险中数据回看的唯一承接处」条](../../06-待办清单.md)(2026-10-04 用户裁决 P-C7——冒险中不给数据回看,历史战报与结算明细的查看去向 = 新「生涯」界面)。 +> **来源**:[待办清单「『生涯』界面——冒险中数据回看的唯一承接处」条](../../../../待办清单.md)(2026-10-04 用户裁决 P-C7——冒险中不给数据回看,历史战报与结算明细的查看去向 = 新「生涯」界面)。 ## 一、信息架构 @@ -26,11 +26,11 @@ 1. **局内不放生涯入口**。冒险进行中玩家只看状态面板(迭代 17 卡③并行批——局内只读查看钥石与解锁进度);若历史回看能从局内到达,等于绕回 P-C7 退役前的形态,禁止。 2. **生涯内零跳转**。不放「去营地」之类的操作引导,生涯纯只读。 -3. **与 P-C7 的关系**:生涯的成立正是 P-C7 裁决的补偿面——「冒险中无回看」的已知代价由生涯承接(06 条目原文口径),本文不提议在冒险中恢复任何回看入口。 +3. **与 P-C7 的关系**:生涯的成立正是 P-C7 裁决的补偿面——「冒险中无回看」的已知代价由生涯承接(待办清单条目原文口径),本文不提议在冒险中恢复任何回看入口。 ## 二、承载内容清单(逐段标数据可行性) -生涯装三段内容:跨局汇总、历史冒险回看、图鉴。这三段是 06 条目给定的骨架,本节在其上逐项落到数据源。跨局汇总与图鉴的收集类数据大多现成;历史回看的数据面已在存(见下),缺口只有三件,已随 P2 甲裁决定方向。 +生涯装三段内容:跨局汇总、历史冒险回看、图鉴。这三段是待办清单条目给定的骨架,本节在其上逐项落到数据源。跨局汇总与图鉴的收集类数据大多现成;历史回看的数据面已在存(见下),缺口只有三件,已随 P2 甲裁决定方向。 ### 跨局汇总(期一) @@ -40,7 +40,7 @@ | 各关通关次数 | `clear_count(level_index)`(`save_manager.gd:238`) | 现成 | | Boss 首杀与总击杀 | `boss_first_kill_marked`(`save_manager.gd:242`)/ `boss_kill_count`(`:250`) | 现成 | | 钥石余额 | `keystone_balance`(`save_manager.gd:202`) | 现成。累计收支流水不在存(加钥石与花钥石只动余额,`:206`/`:211`)——如要做属新增流水域,期一实装批另呈报,本文只登记 | -| ~~三柜台解锁完成度概览~~ | (整行删——2026-10-12 用户裁:生涯页不统计天赋树与账号成长态,只统计终身计数;数据源 forge_level/workshop_status/tree_nodes 三投影随天赋树实装批退役,07⑲两观测项同步摘除) | — | +| ~~三柜台解锁完成度概览~~ | (整行删——2026-10-12 用户裁:生涯页不统计天赋树与账号成长态,只统计终身计数;数据源 forge_level/workshop_status/tree_nodes 三投影随天赋树实装批退役,体验验证清单⑲两观测项同步摘除) | — | ### 历史冒险回看(期二) @@ -58,9 +58,9 @@ ### 图鉴(期三) -- **敌人图鉴(优先,2026-10-06 用户裁 P3 甲)**:直接承接 06 在册「敌方技能图鉴 / 学习呈现」条(P2——见过 → 认得 → 记谱;归属 [HUD 框架](../表现与支撑/HUD框架.md) 与 [敌人系统](../战斗循环/敌人系统.md))。「见过」记账面 = 新增 meta 域,涉存档 schema 迁移(与期一终身计数域同属 schema 义务面;版本号按实装时点的现行版本顺延)。 +- **敌人图鉴(优先,2026-10-06 用户裁 P3 甲)**:直接承接待办清单在册「敌方技能图鉴 / 学习呈现」条(P2——见过 → 认得 → 记谱;归属 [HUD 框架](../表现与支撑/HUD框架.md) 与 [敌人系统](../战斗循环/敌人系统.md))。「见过」记账面 = 新增 meta 域,涉存档 schema 迁移(与期一终身计数域同属 schema 义务面;版本号按实装时点的现行版本顺延)。 - **秘宝 / 奇物图鉴(随后)**:无在册条目,立项时另行登记。 -- **奖励格图鉴:只登记不激活**(P3 甲)。营地「奖励格图鉴」柜台现况 = 常开独立位(迭代 21 T6 四柜台并排重排——树淬炼柜台升主界面,图鉴本体仍空置、内容排 Alpha);该柜台已随配比预设批整体挂起冻结(2026-10-05 用户令,06 在册),重启须用户另行发令。 +- **奖励格图鉴:只登记不激活**(P3 甲)。营地「奖励格图鉴」柜台现况 = 常开独立位(迭代 21 T6 四柜台并排重排——树淬炼柜台升主界面,图鉴本体仍空置、内容排 Alpha);该柜台已随配比预设批整体挂起冻结(2026-10-05 用户令,待办清单在册),重启须用户另行发令。 ## 三、与既有界面的关系 @@ -80,9 +80,9 @@ |---|---|---|---| | 期一 | 跨局汇总页 + 主菜单生涯入口落位。总局数/通关局数两个终身计数域随该批做存档 schema 迁移——**✅ 已实装(2026-10-07 迭代 18 卡④)**:汇总段六类九项+营地与系统组生涯钮+存档 v6 两终身计数域〔v5 升 v6 幂等迁移〕;闸读数与代拍板追认单原记于该批出口报告,该件已按「吸收即死」在提交 8e02dcf0 删除,读数以本行与该批提交信息为准 | 提纲评审通过。实装批前置义务 = 对齐迭代 16 UI 批后的现行基线:`FS_*` 六档字号 / `TG_*` 语义色 / `BUTTON_MIN_H=40`(`ui_kit.gd:437`)/ 色板单源 / `page_shell` 模态栈纪律(`ui_kit.gd:394`)——与卡③需求卡片同款红线,本文只登记、不展开 | Alpha 后最近一个 UI 窗口 | | 期二 | 历史冒险回看整段:N 扩容 + 用时埋点 + 旧档摘要迁移 + 逐局列表 + 单局明细(`settlement_review_overlay.gd` 复活承接)+ 营地条带处置(P6 裁案落地) | 期一。实装批开工前须向用户呈报两件:N 终值读数(20 / 50 / 维持 10 三选一)与「用时」埋点口径(计时起点、暂停是否计入——字段级细节本文不做) | 期一落地后独立批 | -| 期三 | 图鉴承接(敌人优先,范围与顺序随 P3 甲);「见过」记账面 schema 义务随该批执行 | 期二或独立评估 | Beta 窗口候选(与教学引导同段评估——图鉴的「认得」轴与教学相关;06 教学引导节各条 2026-10-04 起已整体标 Beta 阶段) | +| 期三 | 图鉴承接(敌人优先,范围与顺序随 P3 甲);「见过」记账面 schema 义务随该批执行 | 期二或独立评估 | Beta 窗口候选(与教学引导同段评估——图鉴的「认得」轴与教学相关;待办清单教学引导节各条 2026-10-04 起已整体标 Beta 阶段) | -本地化文案权:生涯界面本体按钮、页签、空态文案归[设置与本地化](../表现与支撑/设置与本地化.md)线(全仓无多语言实装——`game/` 内 grep TranslationServer 零命中;文案权先例 = 教学文案定稿权登记于 06),实装批承接。 +本地化文案权:生涯界面本体按钮、页签、空态文案归[设置与本地化](../表现与支撑/设置与本地化.md)线(全仓无多语言实装——`game/` 内 grep TranslationServer 零命中;文案权先例 = 教学文案定稿权登记于待办清单),实装批承接。 ## 五、待裁点 diff --git a/design/gdd/systems/跨局循环/秘宝.md b/design/gdd/systems/跨局循环/秘宝.md index bf01dec8..fb170f9d 100644 --- a/design/gdd/systems/跨局循环/秘宝.md +++ b/design/gdd/systems/跨局循环/秘宝.md @@ -257,4 +257,4 @@ playtest 预警(预注册,归难度曲线与Boss): ## 待办 -本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。 +本系统待办条目已统一收编至 [待办清单](../../../../待办清单.md),本节不再逐条登记。 diff --git a/design/gdd/systems/跨局循环/锻造工坊.md b/design/gdd/systems/跨局循环/锻造工坊.md index 2cbc3c35..a13e33be 100644 --- a/design/gdd/systems/跨局循环/锻造工坊.md +++ b/design/gdd/systems/跨局循环/锻造工坊.md @@ -1,7 +1,7 @@ # 锻造工坊 > 一句话:营地的武器与护甲成长——武器锻造区三条路线、护甲锻造区三条路线各练各的,钥石消费,一次冒险各选一件,满级特效留位本期不做 -> 状态:**v0.8 迭代 21 反哺④残余写入文档(2026-10-13)**——「树侧钥匙」句换代:钥匙节点 forge_workshop 已随迭代 21 实装在役(free 无前置、点亮展开本柜台、锁定态零购买路径),原「实装归 06」悬置指针终结。承 v0.7 迭代 23 反哺写入(2026-10-13)——正文补 Q1 等级语义衔接(0 = 未练合法态)、效果类型闭集 24→31 订正、实装边界 1 回填实装实态(已随迭代 23 入库)。承 v0.6 完备性检查批(承 v0.5 B 组定案——**17 裁点全数清零**:1 丙 / 1a 一次冒险一件武器+一件甲 / 1b 营地可换·战斗禁换 / 1c 免费 / 2a 伪裁点消解 / 2b 随 3a 消解 / 3a 魔法护甲统一命名 / 3b 敌方攻击缺省普通·克制反向当下生效 / 3c 每型独立路线 / 4a 前缓后陡 / 4b 锻造内自闭环 / 4b-1 并联双通道 / 5b 纯钥石 / 5c 零材料 / 6 满级特效本期不做留扩展位 / 8a 工作间两区定名;2c、5a 已于 v0.4 结案)。**v0.6 变更(2026-10-12 完备性检查批·grilling 用户逐条裁)**:现役事实基线换代(forge_products 行族已随迭代 21 T5 退役、定价参数改历史考古口径);**两根类型轴所有权移交**(默认值归锻造工坊配置常驻持有、hero.tres 静态表两轴删除、选中态写存档+参数面注入);「与秘宝混合制同构」与「激活穿刺系专长」两处无依据表述订正删除。**满级特效本期不做**(只留扩展位);全部数值 provisional,终值归 Alpha 收官 M4 数值批〔未排期〕;实装已随迭代 23 入库(2026-10-12) +> 状态:**v0.8 迭代 21 反哺④残余写入文档(2026-10-13)**——「树侧钥匙」句换代:钥匙节点 forge_workshop 已随迭代 21 实装在役(free 无前置、点亮展开本柜台、锁定态零购买路径),原「实装归待办清单」悬置指针终结。承 v0.7 迭代 23 反哺写入(2026-10-13)——正文补 Q1 等级语义衔接(0 = 未练合法态)、效果类型闭集 24→31 订正、实装边界 1 回填实装实态(已随迭代 23 入库)。承 v0.6 完备性检查批(承 v0.5 B 组定案——**17 裁点全数清零**:1 丙 / 1a 一次冒险一件武器+一件甲 / 1b 营地可换·战斗禁换 / 1c 免费 / 2a 伪裁点消解 / 2b 随 3a 消解 / 3a 魔法护甲统一命名 / 3b 敌方攻击缺省普通·克制反向当下生效 / 3c 每型独立路线 / 4a 前缓后陡 / 4b 锻造内自闭环 / 4b-1 并联双通道 / 5b 纯钥石 / 5c 零材料 / 6 满级特效本期不做留扩展位 / 8a 工作间两区定名;2c、5a 已于 v0.4 结案)。**v0.6 变更(2026-10-12 完备性检查批·grilling 用户逐条裁)**:现役事实基线换代(forge_products 行族已随迭代 21 T5 退役、定价参数改历史考古口径);**两根类型轴所有权移交**(默认值归锻造工坊配置常驻持有、hero.tres 静态表两轴删除、选中态写存档+参数面注入);「与秘宝混合制同构」与「激活穿刺系专长」两处无依据表述订正删除。**满级特效本期不做**(只留扩展位);全部数值 provisional,终值归 Alpha 收官 M4 数值批〔未排期〕;实装已随迭代 23 入库(2026-10-12) > 成文底稿:`design/research/提案-武器锻造系统-2026-10-07.md`(提案过程稿——全部备选案与淘汰依据、用户原案逐条对照见彼;本文只收录定案口径;**未启用的满级特效候选池亦留彼 §八**,不进正文) ## 设计目的 @@ -29,7 +29,7 @@ |---|---| | 钥石与营地柜台结构 | [元进度](元进度.md)——本系统即属性锻造柜台攻击/护甲两档的改造,消费货币与柜台框架归彼 | | 数值终值(每级增量/等级上限/价格/基础 AC/特效值) | Alpha 收官 M4 数值批——本文全部数值只有量纲与锚点,标 provisional | -| 代码与数据表落地 | 实装批(待办在册 06)——迁移面见下文,含数值验证义务 | +| 代码与数据表落地 | 实装批(待办在册待办清单)——迁移面见下文,含数值验证义务 | | 克制矩阵与伤害结算 | [战斗结算](../战斗循环/战斗结算.md)——矩阵九格结构冻结是既有条款,本系统零改动 | | 局内属性奖励件 | [奇物](../冒险循环/奇物.md)——账号层永久强化与单冒险加算区分层并存,互不侵入 | | 存档读写 | [存档序列化](../表现与支撑/存档序列化.md)——实装后新增等级与当前选中域,旧档废弃口径随实装批(开发阶段无迁移) | @@ -51,7 +51,7 @@ **工作间内两区并列**(A③ 裁):武器区/护甲区并列呈现,机制层面零顺序门槛;同屏分栏或页签切换=呈现细节归 HUD 批。 -**树侧钥匙(2026-10-11 裁:无前置)**:本柜台由天赋树「锻造工坊」钥匙节点展开——free 节点、**无前置条件、直接可点亮**(原「攻击淬炼累计 ≥2 级 且 护甲淬炼累计 ≥2 级」等级阈值前置,随树脊柱砍攻/护两线作废);未点亮时本柜台锁定态,点亮后开放。树侧结构换代(脊柱砍攻/护两线 + 一线一节点 + Fork 一节点双态,三轮换代 **29→21→15→12**,地脉共鸣条件效果随之换代——2026-10-12 订正:原记「29→21」系 v0.6 时点旧数,树侧现行终态 12 节点)设计权威文档 = [天赋树](天赋树.md);**钥匙节点 forge_workshop 已随迭代 21 实装在役(2026-10-12 入库——free 无前置、点亮展开本柜台、锁定态零购买路径),2026-10-13 反哺写入换代原「实装归 06」悬置指针**。 +**树侧钥匙(2026-10-11 裁:无前置)**:本柜台由天赋树「锻造工坊」钥匙节点展开——free 节点、**无前置条件、直接可点亮**(原「攻击淬炼累计 ≥2 级 且 护甲淬炼累计 ≥2 级」等级阈值前置,随树脊柱砍攻/护两线作废);未点亮时本柜台锁定态,点亮后开放。树侧结构换代(脊柱砍攻/护两线 + 一线一节点 + Fork 一节点双态,三轮换代 **29→21→15→12**,地脉共鸣条件效果随之换代——2026-10-12 订正:原记「29→21」系 v0.6 时点旧数,树侧现行终态 12 节点)设计权威文档 = [天赋树](天赋树.md);**钥匙节点 forge_workshop 已随迭代 21 实装在役(2026-10-12 入库——free 无前置、点亮展开本柜台、锁定态零购买路径),2026-10-13 反哺写入换代原「实装归待办清单」悬置指针**。 **注入衔接(所有权切分,2026-10-11 裁)**:每根数值轴全游戏单一来源——生命/命中唯一入口=树脊柱;**攻击唯一入口=武器路线、AC 唯一入口=甲路线(本系统)**,树零攻防来源(红线)。锻造路线加值 = 当前武器攻击加值 + 当前甲路线 AC 加值,与树淬炼 flat、局内加算区在开局属性注入面分层相加(通道现行事实源 = [元进度](元进度.md)「跨局注入」节);锻造加值只按**当前选中**的武器/甲生效(长剑的练度在换带长枪后回家待命,不丢级、不生效)。 @@ -116,7 +116,7 @@ - **奇物属性件**:分层并存,互不侵入。武器/护甲锻造动的是**账号层基础值**(营地永久强化,冒险开始时经参数面传入);奇物属性件动的是**单次冒险加算区**(关间不清零、冒险结束清零)。本设计不扩奇物"生命/AC/攻击"三轴封闭分类、不动渠道开关表、不往局内池加任何东西。入战 AC 的三层语义清晰可加:甲型基础 AC + 营地甲路线等级加值 + 局内加算区累加。 - **克制矩阵(2a 裁:伪裁点消解)**:**伤害结算只有一套,类型不是待仲裁的槽位**。每份伤害单据自带 `attack_type` 栏(`damage_controller.gd:19` 单据九栏之一)——主角基础攻击单据取 `hero.tres` 的 attack_type(由当前武器决定),棋盘格面直伤件(穿刺弹 / 魔法矢)取 reward 表自身的类型(预期 `reward.tres:131/142`)——各自按**同一张 3×3 矩阵** `armor_effectiveness` 取克制修正(`_counter_delta`)。因此"叠加 / 替代 / 互斥"三分法不成立:两根参数之间无冲突可裁,也不需要任何共存规则。二者的真实差异只在**单据形态与生命周期**(主角基础攻击走掷点折扣 + 暴击;棋盘克制直伤走必中全额不掷点 `_resolve_board_typed`;且前者 = 账号层永久、后者 = 局内一次性)——那是两条不同的伤害来源,不是两种类型语义。矩阵九格满格结构冻结(2b 随 3a 自动消解:魔法护甲 = 现役 ward,不存在第四甲型)。 - **工作间两区定名 + 路线行名(8a 裁)**:锻造工坊工作间内先立两个分区,各装三条锻造路线(路线行名统一为"件名 + 锻造")——①**武器锻造区**:长剑锻造 / 长枪锻造 / 法杖锻造;②**护甲锻造区**:轻甲锻造 / 重甲锻造 / 魔法护甲锻造。两区并列、机制层面零顺序门槛(A③ 裁),区内路线各自独立升级。 -- **局内不存在武器/护甲的提升(8a 裁连带核结)**:用户指出"局内没有可以提升武器的地方"——**属实**。查实:局内商店货架的三行(现役旧名"攻击锻升 / 生命锻升 / 护甲锻升"——**2026-10-12 已改名,见下**),**正是奇物「属性值提升」三轴(攻击 / 生命上限 / AC)的货架前台标签**——`shop.tres` pool_shelf 六行用 `kind_id` 指向 `adventure_table.gd:29` 的 CURIO_KINDS 常量(其中 feat_ticket 为显式豁免种、不入该词表,5/6 命中——`config_db_cross_validator.gd:109-110`),`display_name` 只是这层的前台名;买到的东西进**冒险加算区**、冒险结束清零。所以它们是**奇物属性件**,既不是武器也不是护甲,局内不改变任何锻造等级。命名上的隐患确凿:行名里的"锻"字与营地锻造同字,是误读的直接来源。**2026-10-12 用户裁决(8a 连带·C 项)**:三行按「属性 + 后缀」改名,后缀取 **祝福** ⇒ **攻击祝福 / 生命祝福 / 护甲祝福**(D&D 参照调研:Blessing 为"神赐恩惠"义;用户同时裁定——参考书目里出现过「祝福」一词不构成禁用)。**改名后这三条在语感上彻底脱离"锻造"一词,与营地工作间不再有字面关联**,而结构关系不变(仍是奇物「属性值提升」三轴,机制分类名不动,只改玩家向显示名)。**执行归独立改名小批**(06 在册)——**已于 2026-10-12 执行完毕并合入 master**(commit `0c93a71` / `0144f60`:shop.tres 六行锻升→祝福;reward.tres / status_effects.tres 护甲强化→盾牌加护;smoke_all.gd:1199 断言同步;注记段四处残留肃清;冒烟两跑 864 项 0 失败)。 +- **局内不存在武器/护甲的提升(8a 裁连带核结)**:用户指出"局内没有可以提升武器的地方"——**属实**。查实:局内商店货架的三行(现役旧名"攻击锻升 / 生命锻升 / 护甲锻升"——**2026-10-12 已改名,见下**),**正是奇物「属性值提升」三轴(攻击 / 生命上限 / AC)的货架前台标签**——`shop.tres` pool_shelf 六行用 `kind_id` 指向 `adventure_table.gd:29` 的 CURIO_KINDS 常量(其中 feat_ticket 为显式豁免种、不入该词表,5/6 命中——`config_db_cross_validator.gd:109-110`),`display_name` 只是这层的前台名;买到的东西进**冒险加算区**、冒险结束清零。所以它们是**奇物属性件**,既不是武器也不是护甲,局内不改变任何锻造等级。命名上的隐患确凿:行名里的"锻"字与营地锻造同字,是误读的直接来源。**2026-10-12 用户裁决(8a 连带·C 项)**:三行按「属性 + 后缀」改名,后缀取 **祝福** ⇒ **攻击祝福 / 生命祝福 / 护甲祝福**(D&D 参照调研:Blessing 为"神赐恩惠"义;用户同时裁定——参考书目里出现过「祝福」一词不构成禁用)。**改名后这三条在语感上彻底脱离"锻造"一词,与营地工作间不再有字面关联**,而结构关系不变(仍是奇物「属性值提升」三轴,机制分类名不动,只改玩家向显示名)。**执行归独立改名小批**(待办清单在册)——**已于 2026-10-12 执行完毕并合入 master**(commit `0c93a71` / `0144f60`:shop.tres 六行锻升→祝福;reward.tres / status_effects.tres 护甲强化→盾牌加护;smoke_all.gd:1199 断言同步;注记段四处残留肃清;冒烟两跑 864 项 0 失败)。 - **专长联动**:现役专长均为跨攻击类型通用件(不按 attack_type 分系——既无 normal 条件件、也无 pierce/magic 条件件,`feats.tres` 29 行实证),武器类型差异只经克制矩阵的 matchup 行体现;「选某类型激活某系专长」在本项目专长体系下不成立(2026-10-12 v0.6 订正:原「选长枪激活穿刺系专长的价值」为无现役对应物的表述,删除)。现有死条件 `magic_vs_magic`(魔法打"魔法甲"——现行甲域无此型,永不可触发 = 废卡):**改值复活案已作废(2026-10-11 D 组核结——所属件魔网织者在素材库表二专长 27 件退役删除名单)**,该行随专长退役删行批整体消解,本系统零触碰(2026-10-12 订正:本节原写"推荐复活"与实装边界第 3 条结案口径冲突,随本批对齐)。「魔法打魔法护甲」的克制语义由矩阵九格承载(magic vs ward = −1),新专长框架如需同类件 = 彼批的新卡设计题。 - **天赋树**:同钥石经济;注入面分层叠加且**所有权切分**(2026-10-11 裁)——树脊柱只持生命/命中淬炼(树零攻防来源),攻/AC 唯一入口=本系统路线加值(只按当前选中武器/甲生效)。 - **冒险前资源配比预设批(挂起冻结中)**:本设计不预设该批的重启口径、不占用其任何冻结裁决、不改其冻结文本。该批重启时须显式核对两处交汇面:①预算包络是否把武器类型计入克制注;②容量柜台与锻造工坊工作间(同在营地)的资源竞争关系。 diff --git a/design/gdd/ux/battle.md b/design/gdd/ux/battle.md index 8307ef6f..46fcf67a 100644 --- a/design/gdd/ux/battle.md +++ b/design/gdd/ux/battle.md @@ -6,7 +6,7 @@ > **Platform Target**: PC (Steam)——Keyboard/Mouse 主(全部操作纯鼠标可完成)、Gamepad Partial 非 MVP、Touch None(同 technical-preferences) > **上游修订依赖**: 弃图刷新挖掘期受理已随布局决策 4 落稿上游(2026-09-12:行动经济 Active 受理 + 每轮上限 2 次、排雷玩法 Active·仅刷新路径装板、战斗结算 `refresh_board` 编排 + 恒 same_board、registry `rap_rules` 同步——见 OQ11) > **Template**: UX Spec -> **覆盖子屏**: 挖掘阶段主界面 · 轮末自动战斗结算(战斗结算明细屏) · 胜利/失败终局 · ~~结算明细回看~~(2026-10-04 P-C7 裁:冒险中回看退役归「生涯」——06 登记) +> **覆盖子屏**: 挖掘阶段主界面 · 轮末自动战斗结算(战斗结算明细屏) · 胜利/失败终局 · ~~结算明细回看~~(2026-10-04 P-C7 裁:冒险中回看退役归「生涯」——待办清单登记) > **输入义务**: 排雷玩法×6 + 行动经济 + 战斗结算×3 + 敌人系统×4 + 增益状态×4 + 地图战斗资源×5(旧版 systems-index 门禁增补记录,缺项即 blocking——承接落点见 §13 义务对照表) --- @@ -48,7 +48,7 @@ 战斗屏是**上下文相关屏**(仅由战斗节点进入),非顶层常驻。关卡内节点进度常驻关卡画面(独立屏的常驻枢纽形态,节点态即进度呈现:已过暗金、当前金、候选通道亮金、Boss 紫赤描边),战斗屏零进度承载——战斗结束返回关卡画面,玩家始终知道自己身处图中第几环。 - 上游屏:关卡画面(选路枢纽,屏级 spec:[level-map.md](level-map.md)——2026-09-27 建档;分支节点图形态,切片第一关为单链特例) -- 下游屏:关卡画面(选路枢纽,spec:[level-map.md](level-map.md))——战斗胜利后返回选路;落地奖励/恢复节点时由关卡画面域开节点覆盖层(NodeOverlay,恢复点全量服务、奖励点=三选一构筑点)确认兑付——节点奖励屏 spec 已出生:[node-reward.md](node-reward.md) v1.0(2026-09-29 迭代 7 T5 顺带出生,06 条目兑现;2026-09-27「不立独立 spec」拍板随之被取代) +- 下游屏:关卡画面(选路枢纽,spec:[level-map.md](level-map.md))——战斗胜利后返回选路;落地奖励/恢复节点时由关卡画面域开节点覆盖层(NodeOverlay,恢复点全量服务、奖励点=三选一构筑点)确认兑付——节点奖励屏 spec 已出生:[node-reward.md](node-reward.md) v1.0(2026-09-29 迭代 7 T5 顺带出生,待办清单条目兑现;2026-09-27「不立独立 spec」拍板随之被取代) - 下游屏:关卡结算([level-clear.md](level-clear.md),末节点 Boss 胜利——2026-09-27 建档) - 平行屏:图例面板 overlay(本屏内域屏);~~结算明细回看 overlay~~(2026-10-04 P-C7 退役——冒险中回看归「生涯」) @@ -105,7 +105,7 @@ - 攻击值 + 修正来源角标(战斗在消费、且站桩上无展示) - 护甲 AC(2026-09-26 二轮拍板补入——我方 AC 的唯一展示面;掷点判定轴,受击侧可读性) - 秘宝槽(四槽壳在役、空槽占位——局内两步使用与关卡域库存随秘宝过渡形态退役〔迭代 11 第①批〕;现行秘宝 = 营地同调装配件,本区展示内容归装配面批次重接) - - 奇物列表(**已实装**——现行标题「特性」,迭代 9 卡⑫ 接线 + 迭代 12 呈现补齐;锻造/大奖励/关卡奖励节点获得的属性提升;与战斗内状态效果分区呈现,防「战斗结束被清」误读。**2026-10-12 奇物呈现修复批整改落地**:原逐流派聚合行退役改逐件行「件名 ×N」,零内部分类字样上屏——原 06「内部分类禁写入玩家可见面」条顺带完成移除) + - 奇物列表(**已实装**——现行标题「特性」,迭代 9 卡⑫ 接线 + 迭代 12 呈现补齐;锻造/大奖励/关卡奖励节点获得的属性提升;与战斗内状态效果分区呈现,防「战斗结束被清」误读。**2026-10-12 奇物呈现修复批整改落地**:原逐流派聚合行退役改逐件行「件名 ×N」,零内部分类字样上屏——原待办清单「内部分类禁写入玩家可见面」条顺带完成移除) - **D 区扫雷图 · AP 条** - AP 点阵 + 停手按钮(现行) - **RAP 读数(点阵+数字)**——自 C 区迁入,置于弃图刷新按钮旁(2026-09-26 拍板:RAP 唯一消费口 = 弃图刷新,资源数字贴消费按钮) @@ -134,7 +134,7 @@ - **对战斗表现双舞台陷阱的输入**:game-concept 登记的"战斗发生在棋盘上还是独立场景"悬念,由本布局裁决为**第三形态:同屏双舞台**。战斗表现定稿前的"战斗表现美术测试"(一屏样张)应按此布局出样 - 敌人不占格(敌人系统已锁)与本布局自洽:敌人实体只存在于 B 区,棋盘永远只有数字/封印印记/小人/变异 -**棋盘格尺寸公式**:`cell = floor(min(D宽−padding, D高−AP条−padding) / N)`,N∈{10,12,13,14}(棋盘生成 D1–D4 行;13×13/14×14 随第三关内容批扩板)。1280×800 下 12×12 → 36px,10×10 → 45px(格边长三方取值不一致已登记 06,扩板定档时统一处置)。数字字号 ≥ 格高的 50%,像素字体整数倍缩放(canvas_items stretch 保证清晰)。 +**棋盘格尺寸公式**:`cell = floor(min(D宽−padding, D高−AP条−padding) / N)`,N∈{10,12,13,14}(棋盘生成 D1–D4 行;13×13/14×14 随第三关内容批扩板)。1280×800 下 12×12 → 36px,10×10 → 45px(格边长三方取值不一致已登记待办清单,扩板定档时统一处置)。数字字号 ≥ 格高的 50%,像素字体整数倍缩放(canvas_items stretch 保证清晰)。 ### Component Inventory @@ -144,7 +144,7 @@ | B | 敌人站桩立绘 ×1–3 | 站桩(无框立绘+落影) | 血条+顺位徽标落底盘(同主角排式,2026-10-06 方案二;**大体档〔显示 >150px 级:drider/duergar_king〕允许向上溢出盒顶 N px(N 由实装批 C0 实算,与背景/光柱无关——现行溢出区为临时光柱氛围层,正式舞台背景插画到位后该层退役,判定不变),血条仍落底**)、状态小图标挂血条正下方(敌方 side-wide 增益各立绘同值呈现——蓄力/硬化/削弱/暴走/警觉;伏击层数通道随 2026-09-20 八型批退役——数据源 = 战斗结算流水经增益状态投影,敌人系统×4④;2026-09-16 敌人技能池批改型:行为环点拆除〔proposal §2.4〕,意图占位 = 本拍摇定结果的动画占位——普通攻击零表示 / 特殊技类型级提示,**意图徽标悬浮头顶上方,探顶档压胸**,敌方增益〔蓄力/硬化〕入状态图标行);死亡灰化加碎裂退场直接演在立绘上(2026-09-20 全站桩拍板,敌人卡退役);血条下名字行 = 纯名字 + 护甲类型图标(形状+色相双通道,与状态图标同行共存,状态空时为纯名字;原「底座下」随石板退位改落底排),AC 数值不展示——2026-09-26 终裁(用户口径:HP 信息已足够,攻防数值不直接写上;护甲类型图标保留克制对策可读性——类型可读、数值隐藏) | 只读 | 新建 | | B | 轮次·阶段指示 | 标签 | "第 N 轮 · 挖掘中/结算中"(终局定格「战斗结束」;Boss 变体附 Boss 名) | 只读 | 新建 | | B | 结算明细带 | 滚动列表 | 结算期逐行流水([战斗结算](../systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋) 9 类行协议);挖掘期收起为上轮摘要 1 行 | 点击展开明细回看 overlay(2026-10-04 P-C7 退役——带保留单行摘要,回看归「生涯」) | battle_log_view.gd 改造 | -| B | ~~结算明细回看~~(已退役) | —— | 2026-10-04 P-C7 裁:冒险中回看退役归「生涯」——settlement_review_overlay.gd 为未接线遗留件(06 登记) | —— | —— | +| B | ~~结算明细回看~~(已退役) | —— | 2026-10-04 P-C7 裁:冒险中回看退役归「生涯」——settlement_review_overlay.gd 为未接线遗留件(待办清单登记) | —— | —— | | C | 攻击数据框 | 直角细线数据框 | 攻击值 + 修正来源角标 + 护甲 AC(AC 二轮拍板 2026-09-26 补入——我方 AC 唯一展示面;原「HP/攻击/RAP 显示」——HP 与 RAP 随信息归属拍板迁出本组件) | 只读 | HUDView 拆分 | | C | 秘宝槽 | 图标槽 ×4 | 四槽壳在役、空槽占位(标题「秘宝」,悬停「秘宝槽(空)」);局内两步使用与关卡域库存随秘宝过渡形态退役——现行秘宝 = 营地同调装配件(秘宝.md),本区展示重接归装配面批次 | 悬停 tooltip | hero_info_panel_view.gd | | C | 奇物列表(现行标题「特性」) | 列表/图标行 | 已实装(迭代 9 卡⑫ 接线、迭代 12 呈现补齐;2026-10-12 呈现修复批整改——逐件行「件名 ×N」,零内部分类字样);锻造/大奖励/关卡奖励节点获得的属性提升——中循环数据,因改变战斗数学且无其他展示面准入战斗屏;与战斗内状态效果(B 区站桩)分区,防「战斗结束被清」误读 | 只读 | hero_info_panel_view.gd | @@ -389,7 +389,7 @@ ## Open Questions -1. **Player journey map——已完成(2026-09-27 欠账处置拍板:不建)**:实现前补建的前提随战斗屏实装失效;情绪曲线事实源 = art-bible §2 能量档,真人体验观测与结论回流 = [07-体验验证清单](../07-体验验证清单.md) +1. **Player journey map——已完成(2026-09-27 欠账处置拍板:不建)**:实现前补建的前提随战斗屏实装失效;情绪曲线事实源 = art-bible §2 能量档,真人体验观测与结论回流 = [体验验证清单](../../../体验验证清单.md) 2. **无障碍专项文档——已完成(2026-09-27 拍板:不另立 design/accessibility-requirements.md)**:基线(对比/色弱/字号/闪烁/减动效/纯鼠标/中文字体)权威 = [HUD框架](../systems/表现与支撑/HUD框架.md)「可访问性基线」节;正式分层(文本缩放/色盲模式/按键重映射)归 [设置与本地化](../systems/表现与支撑/设置与本地化.md) 待设计问题清单 #1(设置项全集裁决时定);本 spec §Accessibility 为呈现侧落地承诺 3. **interaction-patterns.md——已建成**(2026-09-12 /team-ui 批当日落稿,本条「未建」系过期陈述):本 spec 引入的四 pattern(双源拒绝反馈/逐行兑现明细带/悬停预承诺光标/点阵资源显示)均已入库成文(pattern 1/3/4/5) 4. **战斗表现美术测试**(game-concept 已登记,战斗表现批次前强制):本 spec 的常驻双舞台分屏(布局决策 1)是测试的布局输入——**敌人卡形态已裁决(2026-09-20 用户看对照样张拍板):全站桩式(无框立绘+底座),主角同样站桩、状态小图标挂血条下,卡片式整体退役**;本 spec 已随裁决改写(原"按卡片式起草"条款作废),站桩式不改变分区结构。对照样张存档 `production/mockups/enemy-card-vs-standee-mockup.html` diff --git a/design/gdd/ux/camp.md b/design/gdd/ux/camp.md index 03e7c433..0185b81a 100644 --- a/design/gdd/ux/camp.md +++ b/design/gdd/ux/camp.md @@ -22,7 +22,7 @@ - 呈现数据源 = MetaProgression 只读投影经组合根喂入;本层不持有系统资源、不算价。 - 退役/封存件呈现语义已随旧目录整体退役消解(探宝罗盘/显影尘/地穴全图卷等状态行已删——迭代 22 旧 12 行删除后目录内零 deferred/retired 态,2026-10-12); -- 双入口框架(主菜单入口+局内状态面板只读入口〔2026-10-13 由「暂停层」改名——游戏非实时无暂停语义〕)的需求面归元进度「解锁双入口框架」节;状态面板入口已实装(2026-10-06 迭代 17 卡③〔时名暂停层〕——实机目检待用户,06 登记条在册),其呈现面不归本 spec。 +- 双入口框架(主菜单入口+局内状态面板只读入口〔2026-10-13 由「暂停层」改名——游戏非实时无暂停语义〕)的需求面归元进度「解锁双入口框架」节;状态面板入口已实装(2026-10-06 迭代 17 卡③〔时名暂停层〕——实机目检待用户,待办清单登记条在册),其呈现面不归本 spec。 ## 秘宝匣柜台呈现细则(迭代 22 实装态,2026-10-12) diff --git a/design/gdd/ux/level-clear.md b/design/gdd/ux/level-clear.md index b316aba3..a8b8417b 100644 --- a/design/gdd/ux/level-clear.md +++ b/design/gdd/ux/level-clear.md @@ -116,7 +116,7 @@ 1. **GP 增量展示面归属——已完成(2026-09-27 用户拍板)**:战斗胜利出现战斗总结结算、展示获得的资源(GP 增量+总量;迭代 10 起追加 Boss/精英钥石增量行);战斗失败出现冒险总结结算、确认后回存档首页。本屏不承载 GP 与钥石,无遗留。两面呈现 spec:[settlement-summary.md](settlement-summary.md) v1.1 2. **末关分支形态**:末关通关时直通冒险结算(现行维持)——随完整屏形态实装批一并定 3. **钥石呈现三面化——已完成(迭代 10 契约 6 推荐案)**:战斗总结结算(Boss/精英击杀增量行)+ 冒险总结结算(收束明细)+ 营地存量——「进账时刻 / 收束明细 / 存量可用」不同义不构成重复展示;本屏旧「钥石增量+累计」呈现随大奖励重构退役 -4. **视觉终稿**:以表现层样张过审为前置(06 待办登记);本 spec 的 AC 为功能性判据,不含视觉终稿判据。**本批渲染层验证冻结(用户 2026-10-01)**——实装后目检清单顺带交付,实机目检待用户批准后补闸 +4. **视觉终稿**:以表现层样张过审为前置(待办清单登记);本 spec 的 AC 为功能性判据,不含视觉终稿判据。**本批渲染层验证冻结(用户 2026-10-01)**——实装后目检清单顺带交付,实机目检待用户批准后补闸 5. **替换子交互视觉形态——已随渠道退役**:秘宝件出池后本屏无道具件候选,替换子交互不于本屏触发(原功能性判据留档) --- diff --git a/design/gdd/ux/settlement-summary.md b/design/gdd/ux/settlement-summary.md index f3d298a4..e321f8bc 100644 --- a/design/gdd/ux/settlement-summary.md +++ b/design/gdd/ux/settlement-summary.md @@ -6,7 +6,7 @@ ## 定位 -本 spec 承载两个**已实装**的结算总结呈现面(2026-09-27 用户拍板定名,接线登记 06 状态记录): +本 spec 承载两个**已实装**的结算总结呈现面(2026-09-27 用户拍板定名,接线登记待办清单状态记录): - **战斗总结结算**——冒险模式普通战斗胜利时的总结覆盖层(战斗小循环的出口呈现); - **冒险总结结算**——冒险终结(倒下 / 末关通关 / 放弃)时的终局覆盖层(冒险大循环的收束呈现)。 @@ -24,13 +24,13 @@ ## 冒险总结结算(冒险终结面) - 触发:主角倒下(verdict=lose)/ 末关通关 / 玩家放弃——三结局同面(`adventure_finished` 收束)。 -- 载体:与战斗面同一个 battle_end_overlay(2026-09-29 迭代 6 T7 接线)——末关通关走 `open_victory`(金蜡封 +「本局 GP 入账 · 合计 N」行,GP 收束清零前的呈现侧影子账);倒下 / 放弃走 `open_defeat`(暮蓝)。无独立「冒险终局面板」实体,06 状态记录旧称随本条完成。 +- 载体:与战斗面同一个 battle_end_overlay(2026-09-29 迭代 6 T7 接线)——末关通关走 `open_victory`(金蜡封 +「本局 GP 入账 · 合计 N」行,GP 收束清零前的呈现侧影子账);倒下 / 放弃走 `open_defeat`(暮蓝)。无独立「冒险终局面板」实体,待办清单状态记录旧称随本条完成。 - 呈现内容:冒险摘要五件事(定义归[冒险结构](../systems/冒险循环/冒险结构.md))+ 钥石写入明细(= 本局逐杀 Boss 掉落合计;消费归[元进度](../systems/跨局循环/元进度.md) settle_adventure——迭代 10 起大奖励面不再产钥石)+ GP 合计行。 - 出口:确认 → 回存档首页。 ## 口径 -- **命名(2026-09-27 拍板文本口径)**:战斗总结结算 / 冒险总结结算。历史变体退役清单(正文一律改用正名):①「战斗结算画面」——battle.md 旧口径(06 归属行已判登记偏差);②「结算画面」单用——两义词(level-clear 语境=冒险面、battle 旧语境=战斗面),禁用;③「战斗胜利总结结算」——level-clear 与 06 状态记录旧用四字变体;④「摘要结算画面」——冒险结构 旧称(冒险总结结算的摘要呈现位);⑤「冒险终局面板」——06 状态记录对同一 overlay 冒险面打开形态的俗称,无独立实体。06-待办清单 现状段按其「措辞不改」体例保留历史原文,以本清单为命名准绳。 +- **命名(2026-09-27 拍板文本口径)**:战斗总结结算 / 冒险总结结算。历史变体退役清单(正文一律改用正名):①「战斗结算画面」——battle.md 旧口径(待办清单归属行已判登记偏差);②「结算画面」单用——两义词(level-clear 语境=冒险面、battle 旧语境=战斗面),禁用;③「战斗胜利总结结算」——level-clear 与待办清单状态记录旧用四字变体;④「摘要结算画面」——冒险结构 旧称(冒险总结结算的摘要呈现位);⑤「冒险终局面板」——待办清单状态记录对同一 overlay 冒险面打开形态的俗称,无独立实体。待办清单现状段按其「措辞不改」体例保留历史原文,以本清单为命名准绳。 - **GP / 钥石呈现分工**(battle.md OQ14 完成口径 + 迭代 10 扩):GP = 本 spec 战斗面(增量+总量)+ 关卡画面常驻总量;钥石 = 本 spec 战斗面(Boss/精英击杀增量行,迭代 10 起)+ 冒险面(收束明细)+ 营地存量。钥石多处并存系「进账时刻 / 收束明细 / 存量可用」不同义,不构成重复展示(level-clear.md OQ3 完成维持)。 - **失败面不呈战利品**:冒险总结结算不呈现 GP 增量(倒下即终语义,失败侧恒不呈现)。 - **禁重复展示**:本面不呈状态效果、不呈结算明细正文(明细回看 overlay 已随 P-C7 退役——冒险中明细回看归「生涯」)——[battle.md](battle.md) 信息归属两原则(循环限定 + 单一展示面)对面级呈现同样适用。 diff --git a/design/gdd/ux/shop.md b/design/gdd/ux/shop.md index c656df57..520ce8b4 100644 --- a/design/gdd/ux/shop.md +++ b/design/gdd/ux/shop.md @@ -13,7 +13,7 @@ - 模态覆盖层(dim + 居中):标题「商店」/ GP 余额读数/ 令牌级货架卡(进店自共享池抽 3 张:显示名·效果·现价——六行池面含回复与专长凭证;买一件 = 池少一件、货架随即全架重抽)/ 购买按钮(余额不足禁用置灰——pattern 8 禁用态即理由)/ 刷新按钮(GP 付费刷新,价 = ceil(20×1.8^本次进店已付费刷) provisional,余额不足禁用)/ 离开按钮。 - 购买意图 `buy_requested` 经组合根转发 runner(pool 模式载荷 = kind_id);成功后货架整架重建(买 1 全重抽反馈)。刷新意图 `refresh_requested` 经组合根转发 presenter。 - 离开 → 关卡画面兑付确认回选路(零自动推进)。 -- 刷新与货架口径(2026-10-04 P-C2+Q2 裁决,SR-1 落码):基础免费 0 次 + GP 付费刷新 + 池源同源(与三选一同一令牌库本)——原「无独立刷新、全陈列」裁决随该批被推翻;天赋侧「刷新次数」增益预留 free_count 位(06 登记条在册)。 +- 刷新与货架口径(2026-10-04 P-C2+Q2 裁决,SR-1 落码):基础免费 0 次 + GP 付费刷新 + 池源同源(与三选一同一令牌库本)——原「无独立刷新、全陈列」裁决随该批被推翻;天赋侧「刷新次数」增益预留 free_count 位(待办清单登记条在册)。 ## 口径 diff --git a/design/gdd/术语表.md b/design/gdd/术语表.md index f2cdb7bb..98adb74b 100644 --- a/design/gdd/术语表.md +++ b/design/gdd/术语表.md @@ -93,7 +93,7 @@ | 术语 | 定义 | |---|---| | 逐需求点验收清单 | 需求卡片验证闸的必备清单:每个需求点列明测什么(具体断言或行为)/怎么测(测试落点与注入方式)/谁验(自动闸或用户目检);查不出验收条目的需求点=卡片不成立(规矩见 req-card 技能,测试落码写法见 [code-conventions](../engineering/code-conventions.md) §3.5) | -| 测试方式两分法 | 能力验证与体验验证分开走(2026-10-11 用户定):能力验证=通过调试接口直接修改游戏数据(改钥石/槽位/解锁状态等,不走正常资源积累流程);体验验证=用户目检完整流程,登记 07-体验验证清单观测项 | +| 测试方式两分法 | 能力验证与体验验证分开走(2026-10-11 用户定):能力验证=通过调试接口直接修改游戏数据(改钥石/槽位/解锁状态等,不走正常资源积累流程);体验验证=用户目检完整流程,登记体验验证清单观测项 | ## 用语规范(2026-10-15 用户令立) diff --git a/roadmap.md b/roadmap.md index 29e6bd76..86c9f7d7 100644 --- a/roadmap.md +++ b/roadmap.md @@ -1,19 +1,19 @@ # 工程路线图(批次执行制:里程碑 + 批次序列 + loop 规范) -> 一句话:项目级进度视图——走到哪了、接下来按什么顺序走、每个批怎么跑。待办与待裁事项以 [06-待办清单](design/gdd/06-待办清单.md) 为唯一登记处(条目级);批次过程与结论查 git 提交信息与 `reports/`(2026-10-18 用户裁:根目录会话状态文件已废除,本节顶部「当前位」三行即其替代)。 +> 一句话:项目级进度视图——走到哪了、接下来按什么顺序走、每个批怎么跑。待办与待裁事项以 [待办清单](待办清单.md) 为唯一登记处(条目级);批次过程与结论查 git 提交信息与 `reports/`(2026-10-18 用户裁:根目录会话状态文件已废除,本节顶部「当前位」三行即其替代)。 ## 当前位(只回答「现在该做什么」;三行内随批次换代,禁止在此扩写成状态快照) - **阶段**:M3——Alpha 版本的完整实现(2026-10-09 立规:未明令宣布完成前停留 M3,迭代只排 M3 需求,M4 不排期;根目录 stage.txt 为旧阶段开关仅存档)。 - **迭代位**:迭代 1–31 全部已完成或已终止;**迭代 32 待开工**(卡①代码注释禁用词清扫批+卡②效果引擎无状态化批,2026-10-20 编入,执行序①→②)。 -- **下一步**:迭代 32 开工令(U0)归用户发。其余候选在 06 状态列——营地交互重做五卡(已写卡待编迭代)、冒险前资源配比预设(备选)、迭代 30 原卡②③(待美术/设计定稿后重新立卡)、玩家面残留禁字清扫(待写卡)。 +- **下一步**:迭代 32 开工令(U0)归用户发。其余候选在待办清单状态列——营地交互重做五卡(已写卡待编迭代)、冒险前资源配比预设(备选)、迭代 30 原卡②③(待美术/设计定稿后重新立卡)、玩家面残留禁字清扫(待写卡)。 ## 里程碑时间线 | 时间 | 里程碑 | |---|---| | 2026-09-07 ~ 09-14 | Systems Design 阶段:玩法系统 GDD 全树收口;概念原型 v3 终验 PROCEED(09-12,垂直切片承接);GDD 体系重构(09-14,旧树封存) | -| 2026-09-15 ~ 09-16 | 切片数值语言定型:格面资源批、加法核数值语言拍板、护甲等级掷点批落地(smoke 233)、AP6+AC 验收判读口径 v1.0、06-待办清单建账改版 | +| 2026-09-15 ~ 09-16 | 切片数值语言定型:格面资源批、加法核数值语言拍板、护甲等级掷点批落地(smoke 233)、AP6+AC 验收判读口径 v1.0、待办清单建账改版 | | 2026-09-17 ~ 09-19 | 切片机制完备:敌人技能池批落地(smoke 263)、关卡节点地图 v1.0 定稿+分支图批、加法核 80 遍试玩基线、无伤通关根因批(AP 压速)、验收读数重测批、掷点流种子偏置修复 A+B、插旗不可逆批、worktree 铁律立规 | | 2026-09-20 ~ 09-21 | **一局完整冒险闭合**:冒险结构实现批(三关正式序列,smoke 482)、GP+商店房批(smoke 437)、存档序列化批(smoke 518)、元进度实现批(跨局循环闭合,smoke 549)、第三关内容批、八型批 | | 2026-09-22 | Package B 七轮数值批+成长对齿已入库(用户拍板接受 B 曲线);美术圣经 §6–9 全章成文(v2.0);balance-verifier 数值验证工具批;美术文档过期账清偿批 | @@ -75,13 +75,13 @@ 1. **一迭代一 loop**:所有更改任务(功能/文档/数值/素材接线)一律进本路线图的迭代,每迭代先立计划书再开工,一个迭代一次合并登记——**零散并行会话退场**(多会话并行 = 冲突源+介入成本;2026-09-27 起单迭代串行执行)。状态记录记「批」= 本文件记「迭代」,同物异名。 2. **例外 = 零碎 bug**:单独会话 mini-loop 修复(修→轻闸→状态记录登记),不立计划书、不占迭代位;同屏同类 bug 攒够一笔可并入下一个迭代当任务卡。 -3. **用户输入闸显式化**:迭代门里所有需要用户表态的点(否决原因/裁决/试玩)登记在 [06-待办清单](design/gdd/06-待办清单.md) 的状态列(待裁决/待美术设计/待写卡),解一个开一个。 +3. **用户输入闸显式化**:迭代门里所有需要用户表态的点(否决原因/裁决/试玩)登记在 [待办清单](待办清单.md) 的状态列(待裁决/待美术设计/待写卡),解一个开一个。 ## 批次 loop 规范(loop engineering) > 模板先例 = 循环 1 计划书(`.zcode/plans/battle-stage-node2d-loop-plan-2026-09-26.md`,已完整跑通收口)。每迭代照此八件成文,缺件不开工。 > -> **迭代粒度界定(对齐敏捷迭代/Sprint)**:一个迭代 = 一句迭代目标 + **3–8 个更改任务** + 一份计划书 loop + 一次合并登记,交付一个可验证增量(≈一次迭代交付)。单交付物不成迭代——并入相邻迭代当任务卡;用户输入闸未解的任务不进迭代(留 06 当 backlog,解闸后编入下一个迭代);**迭代周期 ≈ 一周左右**(2026-10-11 用户裁定——原「软时间盒 ≤3 个工作日,超限即切迭代」系 3abb3bd2 成文时自造、用户从未立过此规,就此废弃)。**里程碑 = 2–4 个迭代的发布级目标 + 出口验收闸(≈Release)**。 +> **迭代粒度界定(对齐敏捷迭代/Sprint)**:一个迭代 = 一句迭代目标 + **3–8 个更改任务** + 一份计划书 loop + 一次合并登记,交付一个可验证增量(≈一次迭代交付)。单交付物不成迭代——并入相邻迭代当任务卡;用户输入闸未解的任务不进迭代(留待办清单当 backlog,解闸后编入下一个迭代);**迭代周期 ≈ 一周左右**(2026-10-11 用户裁定——原「软时间盒 ≤3 个工作日,超限即切迭代」系 3abb3bd2 成文时自造、用户从未立过此规,就此废弃)。**里程碑 = 2–4 个迭代的发布级目标 + 出口验收闸(≈Release)**。 > 1. **计划书**(`.zcode/plans/<迭代名>-loop-plan-<日期>.md`):迭代目标与完成定义 / 现状事实(代码级,开工自行复核)/ 设计契约(违反即返工,标 🔴 触碰=L3 停机)/ 范围边界 / 任务卡 T0..Tn(逐卡估时)/ 验证闸 / 异常分级 / 代拍板白名单。 2. **T0 开工**:建 worktree + 基线复读记档(冒烟/探针/三闸/MC 对拍基准)+ `git status` 归属核对(并行遗留只标旗不碰)。 @@ -90,8 +90,8 @@ 5. **重闸**(批末 Tn):`tools/run_all_gates.sh` **按本批改动域跑**(触及 `game/` → `--code`,这是代码域唯一触发;不触及 `game/` 的一切路径 → `--docs`;一次改动同批混触两域 → 不带参数全量),所选域全绿——闸件清单、顺序与域划分只在该脚本里定义,本文件与 AGENTS.md/规约均不另列;改闸件自身(`tools/` 下机检脚本与闸壳)不占合回全量,质量义务=落批时的变异验证;涉核心的 MC 与基线逐位比对、素材批的机检断言另行。 6. **人闸**(停机交付):真人目检清单 + 代拍板追认清单 + 异步终审触点(样张类)——本循环内唯一必经人审。 7. **异常分级**:L1 自救(一次重试)→ L2 记录继续(连续 3 次同红灯升级)→ L3 停机写报告等用户。 -8. **批次完成后的五步登记**:①06 条目状态按 doc-conventions §12.1 推进(做完整条删除)②本文件顶部「当前位」三行换代,涉及里程碑移动时同步里程碑表 ③**实现批禁写本文件与 `design/`**(代码实现批只准写 `reports/`),该改哪一行写进 `reports/iter-反哺点-<日期>.md`,由文档批执行 ④阶段变更改 stage.txt ⑤批末闸序列**按本批改动域**全绿留痕(回执 commit 对齐分支尖)。 +8. **批次完成后的五步登记**:①待办清单条目状态按 doc-conventions §12.1 推进(做完整条删除)②本文件顶部「当前位」三行换代,涉及里程碑移动时同步里程碑表 ③**实现批禁写本文件与 `design/`**(代码实现批只准写 `reports/`),该改哪一行写进 `reports/iter-反哺点-<日期>.md`,由文档批执行 ④阶段变更改 stage.txt ⑤批末闸序列**按本批改动域**全绿留痕(回执 commit 对齐分支尖)。 ## 维护纪律 -同「批次 loop 规范」第 8 条五步登记;本文件由里程碑移动与「当前位」换代触发更新(批次开工不强制改本文件,待办明细改 06)。「当前位」限三行,装不下的细节进 06 条目与 git 提交信息。 +同「批次 loop 规范」第 8 条五步登记;本文件由里程碑移动与「当前位」换代触发更新(批次开工不强制改本文件,待办明细改待办清单)。「当前位」限三行,装不下的细节进待办清单条目与 git 提交信息。 diff --git a/tools/doc_term_audit.py b/tools/doc_term_audit.py index b2bf485a..28e54004 100644 --- a/tools/doc_term_audit.py +++ b/tools/doc_term_audit.py @@ -121,7 +121,7 @@ TERM_CONTEXT_EXEMPT = { # 敌人 id 只能读作历史留档(真正的现行规格在 敌人系统.md「目标顺位与意图线索」节)。 "伏击": re.compile(r"ambusher|成文占位"), "heavy_multiplier|重击倍率": re.compile(r"ambusher|heavy_multiplier|成文占位"), - # 拔旗(2026-09-19 退役「旗无移除手段」):06 待办清单「件派生动词白名单」条目说的是 + # 拔旗(2026-09-19 退役「旗无移除手段」):待办清单「件派生动词白名单」条目说的是 # 「将来件池 ≥30 种后可能开放的第三盘面动作」,是待评估的设计意图而非在用机制。 "拔旗|撤旗": re.compile(r"件派生动词白名单|第三盘面动作|非信息类"), } diff --git a/tools/gdd_lint.py b/tools/gdd_lint.py index de662260..3822258f 100644 --- a/tools/gdd_lint.py +++ b/tools/gdd_lint.py @@ -10,12 +10,11 @@ r"""gdd_lint.py — GDD lean 格式门禁 规则(口径权威 = design/engineering/doc-conventions.md 第 5–6 节文档骨架与结构纪律): R1 散文段落 ≤ 240 字(代码块/表格/列表/引用不计) R3 正文禁止修订注记:~~删除线~~、"作废"、括号内"日期+评审/修订/拍板/裁决/核销" - (登记处/清单按 RULE_EXEMPT 分域豁免) R4 禁止变更记录节:出现「版本历史/修订记录/变更记录/修改记录/更新记录/更新日志」标题即红 (沿革只进 git commit log;扫描面 = 全 design/ + roadmap.md,见 --changelog-only) - R5 流程/状态类章节必须含代码块图(字符画或 Mermaid);清单节/词条节按 RULE_EXEMPT 分域豁免 + R5 流程/状态类章节必须含代码块图(字符画或 Mermaid);词条节按 RULE_EXEMPT 分域豁免 R6 表格列数一致(含转义 \| 识别) - R7 括号嵌套跨度 ≤ 80 字(长括号 = 审计注记挤进正文的信号;登记处/清单按 RULE_EXEMPT 分域豁免) + R7 括号嵌套跨度 ≤ 80 字(长括号 = 审计注记挤进正文的信号) R8 核心规则表:规则列必须是"谁·何时·做什么"陈述句所在的可读表——说明/要点列 禁止出现编号引用(AC-x/F-x/EC-x/E-x/OQ-x/Rule-x/义务),引用只允许在依据类列 R9 一页纸节点:任一标题节点的直接内容(到下一标题为止)≤ 80 行——装不下就拆子节点 @@ -35,26 +34,14 @@ MAX_PARA = 240 MAX_PAREN_SPAN = 80 # 规则分域(2026-10-03 用户裁「测试要快/要准」优化批):R1 的体裁前提是「规范文」 -# (短段+表格化);登记处/清单的自然形态就是长条目与叙事散文,硬套=自 2026-09-20 -# 上线起 8/8 常红零过滤价值(test-perf-report-2026-10-02 §6.2 实证)。R3/R7 不豁免—— -# 「provenance 出正文」对一切体裁有效;R4 变更记录节禁令自 2026-10-19 起对一切体裁有效。 -R1_EXEMPT = { - "06-待办清单.md", # 全项目待办登记处:现状/状态/方案长条目为体裁 - "07-体验验证清单.md", # 体验验证读数清单:同上 -} +# (短段+表格化)。「provenance 出正文」对一切体裁有效;R4 变更记录节禁令自 2026-10-19 +# 起对一切体裁有效。 # 规则粒度分域豁免(2026-10-15 用户令「清单类文件与术语表不做 GDD 规范性检查」)。 -# 原则:**按规则豁免,不按文件拉黑**——体裁规则(R3/R5/R7)对登记处/清单/词条表 -# 不适用,但机械可判的完整性规则(R4/R6/R8/R9/R11)一律不豁免,真缺陷不得藏起来。 -# 各条理由: -# R3 正文禁修订注记——登记处/清单的条目「带日期+裁决来源」是设计目的本身 -# (条目要能回答「这条谁在何时裁的」),禁它等于禁登记处的核心价值。 -# R5 流程/状态类节须含代码块图——节名含「流程/生命周期」即触发,但 07 的 -# 「㉖…全流程走查」「㉗…目检」是目检清单节、术语表的「开发流程」是词条节, -# 两者都不是流程描述,属节名误匹配。 -# R7 括号跨度 ≤80 字——长括注在登记处/清单里是常态(现状+裁决+归属挤在一行)。 +# 原则:**按规则豁免,不按文件拉黑**——体裁规则对词条表不适用,但机械可判的完整性规则 +# (R4/R6/R8/R9/R11)一律不豁免,真缺陷不得藏起来。 +# R5 流程/状态类节须含代码块图——节名含「流程/生命周期」即触发,术语表的「开发流程」 +# 是词条节、不是流程描述,属节名误匹配。 RULE_EXEMPT = { - "06-待办清单.md": {"R3", "R7"}, - "07-体验验证清单.md": {"R3", "R5", "R7"}, "术语表.md": {"R5"}, } @@ -181,17 +168,16 @@ def lint_file(path): issues.append(f"R9 节点「{node_name}」直接内容 {node_count} 行(>{MAX_NODE_LINES})——超一页,拆为子节点") infos.append(f"最大节点直接内容 {max(node_count, 0)} 行") - # R1 段落长度(登记处/清单文分域豁免,见 R1_EXEMPT 注) + # R1 段落长度 fname = Path(path).name ex = RULE_EXEMPT.get(fname, set()) # 规则粒度分域豁免(见 RULE_EXEMPT 注) - if fname not in R1_EXEMPT: - for p in paras: - if len(p) > MAX_PARA: - issues.append(f"R1 散文段 {len(p)} 字(>{MAX_PARA}): {p[:50]}…") + for p in paras: + if len(p) > MAX_PARA: + issues.append(f"R1 散文段 {len(p)} 字(>{MAX_PARA}): {p[:50]}…") # R2 表格占比已停用(见文件头注释)。 - # R3 修订注记(代码块豁免;登记处/清单按 RULE_EXEMPT 豁免——变更记录节已整体禁设,无豁免域) + # R3 修订注记(代码块豁免;变更记录节已整体禁设,无豁免域) body_no_code = "\n".join(l for l in text.splitlines() if l not in code_lines) for m in (() if "R3" in ex else re.finditer(r"~~.+?~~", body_no_code)): issues.append(f"R3 删除线残留: …{m.group(0)[:40]}…") diff --git a/tools/log_analysis.py b/tools/log_analysis.py index b7db4116..1d247f1e 100644 --- a/tools/log_analysis.py +++ b/tools/log_analysis.py @@ -166,7 +166,7 @@ class RunAcc: self.end_hp = int(e.get("hp", 0)) def on_action(self, e): - # 刷新经济监控(07 清单⑦):只计受理成功的弃图刷新——被拒尝试不构成弃图。 + # 刷新经济监控(体验验证清单⑦):只计受理成功的弃图刷新——被拒尝试不构成弃图。 if e.get("op") == "refresh" and e.get("accepted"): self.refresh_count += 1 @@ -514,7 +514,7 @@ def render(res_files, args, out): print("== 关卡级统计 ==", file=out) print(" 口径:局=run 行切分(无 run 行的旧日志整文件一局);通关=result=victory;", file=out) print(" 进BossHP=Boss首结算快照HP+首轮承伤−首轮治疗(精确反推);平均轮数=每局settlement数。", file=out) - print(" 弃图率=每局受理刷新次数(07⑦ 基线读数,与 MC 刷新/局同口径);", file=out) + print(" 弃图率=每局受理刷新次数(体验验证清单⑦ 基线读数,与 MC 刷新/局同口径);", file=out) print(" 每轮刷新率=刷新次数÷结算轮数(组内加权)。阈值数字归调参批,本表只出基线。", file=out) hdr = (f" {'关卡':>6} {'档位':>8} {'局数':>5} {'通关率':>7} {'平均轮数':>8} {'进BossHP均':>10} " f"{'通关剩余HP均':>12} {'整局承伤均':>10} {'弃图率':>7} {'每轮刷新率':>9}") diff --git a/tools/pipeline_gate.py b/tools/pipeline_gate.py index 47ed8a16..04145dd8 100644 --- a/tools/pipeline_gate.py +++ b/tools/pipeline_gate.py @@ -1,15 +1,15 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -r"""pipeline_gate.py — 工作流程流水线闸(06 条目状态机+roadmap 迭代总表+需求卡片口径+一次交叉核)。 +r"""pipeline_gate.py — 工作流程流水线闸(待办清单条目状态机+roadmap 迭代总表+需求卡片口径+一次交叉核)。 -职责:机检 06 条目(标题元数据/属性齐备/状态词白名单/条件凭据/状态段累积制在场约束/特批/ +职责:机检待办清单条目(标题元数据/属性齐备/状态词白名单/条件凭据/状态段累积制在场约束/特批/ 零命中)与 roadmap 迭代总表(六列/状态四形态/卡片与报告存在性/编入时间与预计周期的 历史行「—」豁免/周期≤2 周可特批豁免/单元格白名单/零命中);「已编迭代↔已写卡段↔迭代行 卡片列」交叉核只此一处。2026-10-18 卡片冲突修订批补两条卡片机检:C1 关联文档同步面的 文档义务口径(生效 2026-10-17)、C2 设计事实源声明(生效 2026-10-18)——两条都按文件名 日期只追新规生效日之后的卡,旧卡属 git 历史留档不回头改。 约束:每红项一行「文件:行号 判据名 一句白话说明」,exit 0=全绿 / 1=有红 / 2=输入件缺失; - 卡片与报告存在性相对 --repo-root 解析(缺省=本文件上两级);06 与 roadmap 均已为新格式 + 卡片与报告存在性相对 --repo-root 解析(缺省=本文件上两级);待办清单与 roadmap 均已为新格式 (2026-10-18 数据整改批),本闸已注册进 tools/run_all_gates.sh 文档域(08c 流水线闸)。 用法:python tools/pipeline_gate.py [--todo PATH] [--roadmap PATH] [--repo-root PATH] """ @@ -18,7 +18,7 @@ import re import sys from pathlib import Path -DEFAULT_TODO = Path("design/gdd/06-待办清单.md") +DEFAULT_TODO = Path("待办清单.md") DEFAULT_ROADMAP = Path("roadmap.md") SOURCE_WORDS = ("playnote", "会话提及", "审计发现", "批次移交") @@ -200,7 +200,7 @@ def check_status(raw, line, face, issues, where): def check_todo(text, issues, where, root): - """06 全部判据。返回交叉核链(已编迭代条目 → (行号, 迭代号, 卡片路径|None))。 + """待办清单全部判据。返回交叉核链(已编迭代条目 → (行号, 迭代号, 卡片路径|None))。 2026-10-20 状态栏纯化批:闭合类状态词的证据核对从状态栏括号改到现状关联文档 清单(§12.1「状态行只写状态词」)——已写卡对 reports/ 卡片路径+磁盘存在性, @@ -254,7 +254,7 @@ def check_todo(text, issues, where, root): issues.append((where, line, "卡片路径不存在", "现状清单里的卡片路径 %s 相对仓库根不存在" % rp)) # 证据核对二:文档轨闭合/反哺已写入 → 现状清单须有文档路径+版本号 - # (06 正文里的指针是相对路径,形如 systems/… 或 design/…,只认 .md 收尾+版本号) + # (待办清单正文里的指针是相对路径,形如 systems/… 或 design/…,只认 .md 收尾+版本号) if "文档设计已闭合" in words or "已写入" in words: if not (re.search(r"[^\s ,,()()]+\.md", xian) and VER_RE.search(xian)): issues.append((where, xline, "正文缺设计定稿指针", @@ -459,8 +459,8 @@ def check_cards(root, issues): def main(): ap = argparse.ArgumentParser( - description="工作流程流水线闸:06 条目状态机+roadmap 迭代总表+一次交叉核") - ap.add_argument("--todo", help="06-待办清单路径(缺省=<仓库根>/design/gdd/06-待办清单.md)") + description="工作流程流水线闸:待办清单条目状态机+roadmap 迭代总表+一次交叉核") + ap.add_argument("--todo", help="待办清单路径(缺省=<仓库根>/待办清单.md)") ap.add_argument("--roadmap", help="roadmap 路径(缺省=<仓库根>/roadmap.md)") ap.add_argument("--repo-root", help="仓库根(卡片/报告存在性的相对基准;缺省=本文件上两级)") args = ap.parse_args() @@ -484,7 +484,7 @@ def main(): if issues: print("流水线闸 FAIL:红项 %d" % len(issues)) return 1 - print("流水线闸 PASS:06 条目 %d · 总表数据行 %d · 交叉核 %d 链 · 卡片口径 %d 张全过" + print("流水线闸 PASS:待办清单条目 %d · 总表数据行 %d · 交叉核 %d 链 · 卡片口径 %d 张全过" % (len(parse_todo(todo_text)), len(index), len(links), n_cards)) return 0 diff --git a/tools/render_gate.sh b/tools/render_gate.sh index 3ca4a1ac..b0cef79d 100644 --- a/tools/render_gate.sh +++ b/tools/render_gate.sh @@ -7,7 +7,7 @@ # 段: # ① shot_probe 七屏窗口化截图(menu/settings/career/camp/level/battle/status) # → tools/shot_checker.py A-D 语义断言自动判定(A 屏级骨架全屏/B 文字对比度/C 明度三档带/ -# D 文字禁压纹理;E 焦点预算=语义面仍归人闸不机检)。首跑存量 FAIL 按 S1 停机点全量呈报登记 06。 +# D 文字禁压纹理;E 焦点预算=语义面仍归人闸不机检)。首跑存量 FAIL 按 S1 停机点全量呈报登记待办清单。 # ② 取证段(Q7:超时/零字节/文件缺失任一即 FAIL——「渲染真实发生」必须成立,不做像素判定): # fx_shot_probe 三时刻抓帧(行到达/结算排播/轮末连帧)+ board_shot_probe L1-L3 棋盘抓帧。 # ③ 棋盘 golden 逐像素:board 整屏帧按 board_meta.json 取样坐标裁剪棋盘区 @@ -64,7 +64,7 @@ fi if [ "$_rc" -eq 0 ]; then python tools/shot_checker.py "$SHOT" shot_menu.png shot_settings.png shot_career.png shot_camp.png shot_level.png shot_battle.png shot_status.png | sed 's/^/[render_gate] /' _rc="${PIPESTATUS[0]}" - [ "$_rc" -ne 0 ] && echo "[render_gate] FAIL — shot_checker A-D 断言存在红(S1 停机点:首跑存量 FAIL 全量呈报登记 06)" + [ "$_rc" -ne 0 ] && echo "[render_gate] FAIL — shot_checker A-D 断言存在红(S1 停机点:首跑存量 FAIL 全量呈报登记待办清单)" fi echo "======== fx_shot_probe 三时刻取证(Q7) ========" diff --git a/tools/repo_structure_audit.py b/tools/repo_structure_audit.py index 025695fb..b95c74ac 100644 --- a/tools/repo_structure_audit.py +++ b/tools/repo_structure_audit.py @@ -27,7 +27,8 @@ ROOT = Path(__file__).resolve().parent.parent # 清单的家——迭代批禁写 design/,只准往这里写,design/ 全目录对它只读。只放 .md,不放图(图像白名单不含此目录)。 TOP_DIRS = {"archive", "artwork", "design", "game", "sim-data", "tools", "reports"} # 2) 根目录文件白名单 -ROOT_FILES = {"AGENTS.md", "README.md", "roadmap.md", "stage.txt", "review-mode.txt", +ROOT_FILES = {"AGENTS.md", "README.md", "roadmap.md", "待办清单.md", "体验验证清单.md", + "stage.txt", "review-mode.txt", ".gitignore", ".zcodeignore"} # 3) 图像允许目录(相对路径前缀;archive/ 为归档 zip 不扫) # game/tests/golden/(棋盘 golden 基线=机检测试资产非美术素材,素材齐盘态生成入库【基线换代权限 Q6】) diff --git a/tools/run_all_gates.sh b/tools/run_all_gates.sh index 9fa4d1bc..bd416d97 100644 --- a/tools/run_all_gates.sh +++ b/tools/run_all_gates.sh @@ -49,7 +49,7 @@ for _a in "$@"; do done # 控制台编码:本仓库闸件输出中文与 ✅/✗ 符号。Windows GBK 控制台下 python 打印这些字符会抛 -# UnicodeEncodeError——06/10 两闸直接崩(假红)、09 的 FAIL 行被写成乱码字节(指纹漂移, +# UnicodeEncodeError——待办清单/10 两闸直接崩(假红)、09 的 FAIL 行被写成乱码字节(指纹漂移, # 与基线比必判「红项清单变化」假红)、末尾汇总自身崩掉打不出结论。 export PYTHONIOENCODING=utf-8 @@ -183,7 +183,7 @@ gate "06 gdd_lint" "gdd_lint.log" "$PY" "$REPO/tools/gdd_lint.py" gate "06b 变更记录节" "changelog.log" "$PY" "$REPO/tools/gdd_lint.py" --changelog-only gate "07 doc_link" "doc_link.log" "$PY" "$REPO/tools/doc_link_audit.py" --strict gate "08 doc_term" "doc_term.log" "$PY" "$REPO/tools/doc_term_audit.py" --strict -# ── 8c. 流水线闸(06 条目状态机+roadmap 迭代总表+一次交叉核,判据=doc-conventions §12)── +# ── 8c. 流水线闸(待办清单条目状态机+roadmap 迭代总表+一次交叉核,判据=doc-conventions §12)── gate "08c 流水线闸" "pipeline.log" "$PY" "$REPO/tools/pipeline_gate.py" fi # ── 6c. 回放确定性对拍(条件闸件;属代码域)── diff --git a/tools/skill_rhythm_audit.py b/tools/skill_rhythm_audit.py index 05b80e32..89721941 100644 --- a/tools/skill_rhythm_audit.py +++ b/tools/skill_rhythm_audit.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """技能池出招节奏审计(消费 playtest_*.jsonl 的 enemy_action 行)。 -对应 06 待办「单拍行为环的体验验证(改型:技能池节奏体验验证)」的机器半边。 +对应待办清单「单拍行为环的体验验证(改型:技能池节奏体验验证)」的机器半边。 判读带: · 过涝 = 敌群连续出特殊技、无普攻基底——读数 = 单敌群同场战斗内最长连续特殊技连击 (连击 ≥3 记过涝信号,连击阈值 3 为代拍板默认:保底 M=4 与冷却 2-4 语义下 2 连属正常波动) diff --git a/design/gdd/07-体验验证清单.md b/体验验证清单.md similarity index 98% rename from design/gdd/07-体验验证清单.md rename to 体验验证清单.md index 23fd6bc9..2919f5a8 100644 --- a/design/gdd/07-体验验证清单.md +++ b/体验验证清单.md @@ -1,6 +1,6 @@ -# 07-体验验证清单 +# 体验验证清单 -本文登记**需要真人体验/观测才能下结论**的验证项,与 [06-待办清单](06-待办清单.md) 分工:06 登记"要拍板的事",本文登记"要玩过才知道的事"。每条注明**结论回流**路径——体验感受不满不等于当场改数:数值终值归其登记的归属批,体验反馈是该批的输入。**登记不阻塞(2026-10-12 用户立规)**:真人检测项登记进本清单后,实现批照常合并进 master、后续迭代照常开工,验收时间由用户自行安排,结论按各条回流路径回流。 +本文登记**需要真人体验/观测才能下结论**的验证项,与 [待办清单](待办清单.md) 分工:待办清单登记"要拍板的事",本文登记"要玩过才知道的事"。每条注明**结论回流**路径——体验感受不满不等于当场改数:数值终值归其登记的归属批,体验反馈是该批的输入。**登记不阻塞(2026-10-12 用户立规)**:真人检测项登记进本清单后,实现批照常合并进 master、后续迭代照常开工,验收时间由用户自行安排,结论按各条回流路径回流。 状态词汇设计权威=增益状态 状态词表节(原提案 v1.0 已按生命周期条款退役,git 提交 7f24b64 可考) @@ -77,7 +77,7 @@ ### ⑧ 封印行为基线监控(封印不可逆批 2026-09-19 落地后的行为监控;原「提案评估前置采集」使命随提案转正终结) -2026-09-19 上午拍板):本项为封印不可逆提案的 Alpha 评估前置采集——同日用户在真人试玩中确认"不能挖旗格"违背设定,**提案全套提前落地**(禁移除 + 挖封印格兑付改判,战斗结算 v0.18 四情况表;登记原文见 2026-09-18 状态记录 72 与 git 历史 06 清单条目)。评估使命终结,本项转为一律机制的真人行为监控(与 ⑥⑦ 同形状,纯日志侧采集零新增埋点)。 +2026-09-19 上午拍板):本项为封印不可逆提案的 Alpha 评估前置采集——同日用户在真人试玩中确认"不能挖旗格"违背设定,**提案全套提前落地**(禁移除 + 挖封印格兑付改判,战斗结算 v0.18 四情况表;登记原文见 2026-09-18 状态记录 72 与 git 历史待办清单清单条目)。评估使命终结,本项转为一律机制的真人行为监控(与 ⑥⑦ 同形状,纯日志侧采集零新增埋点)。 - **观测什么**(读数全部可由现役 JSONL 日志推导——动作行含 flag_place/被拒 dig、结算步流含 flag_hit/flag_miss 判定行〔带格坐标〕与 reward_ineffective 作废行;flag_pull 动作行与同轮插撤、移除次数两读数随移除动作退役作废删除):① 误封率 = flag_miss 判定行 ÷ flag_place 动作行(判定时点口径细节随首批读数钉死);② 挖封印格直挖率 = 封印格直接挖开数 ÷ flag_place 动作行(原「被拒后路径分布」三路径随挖封印格放行消失);③ 四情况触发分布(①标中留判 / ②危险格直挖 / ③标空留判 / ④安全格直挖零奖励——④占比是核心读数)。 - **语义锚(2026-09-19 落地实测锁定,smoke_all `_smoke_flag_irreversible_quadrants` 断言在案)**:封印安全格直挖 = 零惩罚零奖励(正向兑付作废、作废归因行恰一次、标空不判);封印危险格直挖 = 只受挖雷一层惩罚(mine_hit 照常)、标中不发;不挖留判 = 标中/标空照常;flag_pull 出目录拒绝、重复封印 flag_present 拒绝。 @@ -150,7 +150,7 @@ - **策略信号(连锁与微光预读)**:玩家是否更依赖读数字推雷/类型微光预读(免费视野少了,推理工具的使用率应上升)。 - **迷雾联动信号(记忆态使用率)**:视野外扩道具(魔法提灯 +2——已裁退役 2026-10-09,拆线批入库后本信号面失效)与记忆态(暗淡已见格)的使用频率变化。 - **红灯信号**:开局连续多板几乎无免费展开(R₀ 常年 ≈9-15,体感「开局一片黑」);或可推理率体感骤降(数字不够推)。前者=剃雷半径 r 回调面(P1 旋钮 [0,2]),后者归 S1 相变警戒复测。 -- **结论回流**:体感 → 本条目记录;参数终值(r 0/1/2、cap 收紧路径 45→40 等)归 P1-P3 拍板面(读数后置,MC 四带复算挂 07 现行义务),不在试玩现场改数。 +- **结论回流**:体感 → 本条目记录;参数终值(r 0/1/2、cap 收紧路径 45→40 等)归 P1-P3 拍板面(读数后置,MC 四带复算挂体验验证清单现行义务),不在试玩现场改数。 ### ⑭ Boss 半血解锁呈现目检(2026-10-05 技能池执行批顺带登记——迭代14④号卡;D8 呈现面) @@ -236,7 +236,7 @@ ### ㉔ UI 全局主题批全屏巡检(迭代 25 UI 全局主题批顺带登记——2026-10-13) - **引擎默认灰清零巡检**:营地三处滚动容器(含右侧竖滚条)、战斗日志/结算回看的自动滚动条、设置面音量滑轨、各屏悬停气泡(含标题屏深底气泡承旧观感)、调试浮窗种子输入框/批量模拟数/输出区、全屏 15 处分隔线——逐屏看过,应无引擎默认灰色圆角现代风残留。 -- **音量滑轨两段可辨**:把主音量拖到中点,已填充段(深棕)与未填充段(暖石)是否一眼可辨(本批注销 06 第三层①的实机判据)。 +- **音量滑轨两段可辨**:把主音量拖到中点,已填充段(深棕)与未填充段(暖石)是否一眼可辨(本批注销待办清单第三层①的实机判据)。 - **专项观察点 1·滑轨柄是否抢焦点**:设置屏上滑轨柄(烛光黄方柄)是否比「关闭」按钮还抢眼——若是,走 L2 微调(候选降档 STONE 灰石系;色值已冻结,目检前不改)。 - **专项观察点 2·滚动条槽是否看得见**:滚得动的内容里,能否一眼看出滚动条在哪(槽=BG_OVERLAY α0.35)——若否,走 L2 微调(候选提不透明度或改取 SLOT_BACKDROP)。 - **预盖件无实役(登记注记)**:CheckBox / CheckButton / OptionButton 及其弹层 PopupMenu 游戏零使用,本批仅预盖(冒烟 V3 已有运行时证词)——无需目检,备案待未来批次启用时复查。 diff --git a/design/gdd/06-待办清单.md b/待办清单.md similarity index 80% rename from design/gdd/06-待办清单.md rename to 待办清单.md index ebd8a5f6..a22bd434 100644 --- a/design/gdd/06-待办清单.md +++ b/待办清单.md @@ -1,20 +1,20 @@ -# 06-待办清单 +# 待办清单 -本清单是流水线的唯一登记处:要做的事先在此登记一条,随流水线段推进改状态,做完整条删除;各系统文档的「待办」节只留一行指路存根,不再自建条目。条目格式(标题=登记元数据,正文=现状/缺口/归属/状态四属性)与状态机以 [doc-conventions §12.1](../engineering/doc-conventions.md) 为权威。 +本清单是流水线的唯一登记处:要做的事先在此登记一条,随流水线段推进改状态,做完整条删除;各系统文档的「待办」节只留一行指路存根,不再自建条目。条目格式(标题=登记元数据,正文=现状/缺口/归属/状态四属性)与状态机以 [doc-conventions §12.1](design/engineering/doc-conventions.md) 为权威。 #### UI 贴图重构批——营地与元进度件仍是程序化占位(2026-10-13 登记,来源=审计发现,设计面=美术轨) -**现状**:营地的柜台场景贴图目前是程序化画出来的临时形态,没有上贴图。这条债原先只写在美术侧的资产清单里([美术资产清单](../art/art-assets-checklist.md) 第 134 行与第 175 行,原文注明"营地现为程序化占位,状态记录 121⑧ 口径,排期归 UI 贴图重构批"),2026-10-13 由 UI 美化三层诊断转立本清单专条。规格其实已经定了——烛光黄 `#F6C667` 配木色 `#8A5A34`(见 [美术圣经](../art/art-bible.md) §4.4),素材来源允许走"通用图标改色复用"这条低成本渠道。 +**现状**:营地的柜台场景贴图目前是程序化画出来的临时形态,没有上贴图。这条债原先只写在美术侧的资产清单里([美术资产清单](design/art/art-assets-checklist.md) 第 134 行与第 175 行,原文注明"营地现为程序化占位,状态记录 121⑧ 口径,排期归 UI 贴图重构批"),2026-10-13 由 UI 美化三层诊断转立本清单专条。规格其实已经定了——烛光黄 `#F6C667` 配木色 `#8A5A34`(见 [美术圣经](design/art/art-bible.md) §4.4),素材来源允许走"通用图标改色复用"这条低成本渠道。 -**缺口**:还差一次「自己画 vs 找 CC0 素材改色」的美术裁决(见 [美术资产清单](../art/art-assets-checklist.md) §0 的复用渠道闸),裁决后才能定素材工单写卡。 +**缺口**:还差一次「自己画 vs 找 CC0 素材改色」的美术裁决(见 [美术资产清单](design/art/art-assets-checklist.md) §0 的复用渠道闸),裁决后才能定素材工单写卡。 -**归属**:UI 贴图重构批(美术线;须先裁决是自己画还是找 CC0 素材改色,两条备选见 [美术资产清单](../art/art-assets-checklist.md) §0 的复用渠道闸) +**归属**:UI 贴图重构批(美术线;须先裁决是自己画还是找 CC0 素材改色,两条备选见 [美术资产清单](design/art/art-assets-checklist.md) §0 的复用渠道闸) **状态**:待美术设计 #### UI 字体补完——缺拉丁像素字专件、且全局只有一个字重(2026-10-13 登记,来源=审计发现,设计面=美术轨) -**现状**:现在全局只有一套字(`ui_font_fusion_pixel_zh_hans.ttf`,缝合像素字体,中文覆盖好、授权干净,2026-09-27 用户拍板)。但 [美术圣经](../art/art-bible.md) §7.4 定的口径其实是**两套搭配**:拉丁用 Kenney 的像素字、中文用 Fusion Pixel。更要紧的是字重纪律——该条款允许"字号档差 + 墨色深浅 + 字重两档"三个手段一起做信息层级,现在只有单字重,等于层级只能靠字号档差这一个手段,这就是实机上"屏标题看起来不够重、标题跟正文拉不开"的根因([美术素材状态清单](../art/art-status-checklist.md) 把字体标为占位在役,也是这个意思)。 +**现状**:现在全局只有一套字(`ui_font_fusion_pixel_zh_hans.ttf`,缝合像素字体,中文覆盖好、授权干净,2026-09-27 用户拍板)。但 [美术圣经](design/art/art-bible.md) §7.4 定的口径其实是**两套搭配**:拉丁用 Kenney 的像素字、中文用 Fusion Pixel。更要紧的是字重纪律——该条款允许"字号档差 + 墨色深浅 + 字重两档"三个手段一起做信息层级,现在只有单字重,等于层级只能靠字号档差这一个手段,这就是实机上"屏标题看起来不够重、标题跟正文拉不开"的根因([美术素材状态清单](design/art/art-status-checklist.md) 把字体标为占位在役,也是这个意思)。 **缺口**:还差一次「补不补拉丁专件、要不要上第二个字重」的美术裁决,裁决后才能定字体素材工单与 §7.4 的落地口径。 @@ -24,11 +24,11 @@ #### 战斗一屏样张 P0 未开工——界面成品是否过审的那把尺子还没建(2026-10-13 登记,来源=审计发现,设计面=美术轨) -**现状**:[美术圣经](../art/art-bible.md) §7.1 明文写着"程序化占位=临时态,任何屏的终稿闸=§1.4 整屏样张过闸;占位态禁止跨里程碑"。而 [美术素材状态清单](../art/art-status-checklist.md) 把「战斗一屏样张」这件最高优先级的素材标的是**未开始**——也就是说,**判定界面美术算不算过关的那把尺子到现在还没造出来**。2026-10-16 曾编入迭代 30 卡②(UI 呈现三卡批序位②),2026-10-17 用户裁定不满足「迭代=代码实现批」的开发条件、剔除回待设计(理由=样张交付物本身就是设计规格,正式字体与素材均未定稿;同日样张批开工已被用户终止)。v1.4 旧卡留 reports/需求卡片-战斗一屏样张批-2026-10-16.md 作素材,非已写卡状态,重启不得直接开工。 +**现状**:[美术圣经](design/art/art-bible.md) §7.1 明文写着"程序化占位=临时态,任何屏的终稿闸=§1.4 整屏样张过闸;占位态禁止跨里程碑"。而 [美术素材状态清单](design/art/art-status-checklist.md) 把「战斗一屏样张」这件最高优先级的素材标的是**未开始**——也就是说,**判定界面美术算不算过关的那把尺子到现在还没造出来**。2026-10-16 曾编入迭代 30 卡②(UI 呈现三卡批序位②),2026-10-17 用户裁定不满足「迭代=代码实现批」的开发条件、剔除回待设计(理由=样张交付物本身就是设计规格,正式字体与素材均未定稿;同日样张批开工已被用户终止)。v1.4 旧卡留 reports/需求卡片-战斗一屏样张批-2026-10-16.md 作素材,非已写卡状态,重启不得直接开工。 **缺口**:还差「设计讨论→需求澄清→美术定稿」一轮设计(样张即设计目标图,产出尺寸档/色板/明度档清单反向给素材批),定稿后重新立卡方可开发。 -**归属**:美术线(战斗一屏样张的验收标准归 [战斗表现](systems/战斗循环/战斗表现.md) 与 [美术圣经](../art/art-bible.md) §5.1 共裁) +**归属**:美术线(战斗一屏样张的验收标准归 [战斗表现](design/gdd/systems/战斗循环/战斗表现.md) 与 [美术圣经](design/art/art-bible.md) §5.1 共裁) **状态**:待美术设计 @@ -44,9 +44,9 @@ #### 状态面板瘦身——局内面板去跨关解锁内容、只留本局信息(2026-10-16 登记,来源=playnote,设计面=工程直入) -**现状**:playnote 用户反馈:关卡界面中的"状态"面板不需要跨关解锁内容,只显示跟当前冒险有关的信息。现行实态(status_panel.gd 实查)=局内状态面板(2026-10-13 由「暂停层」改名)现为跨局进度镜像:钥石余额徽+「道具工坊 · 解锁态」段(实为秘宝匣 12 行解锁态概览)+「天赋树 · 已购概览」段——恰为用户要去掉的跨关解锁内容。范围=用户原话五件套,零待裁点:面板只留带的秘宝/已获专长/当前属性/现有 GP/钥石总量;秘宝匣解锁态 12 行概览与天赋树已购概览两段退役(跨局解锁概览由营地/生涯承载,局内不再镜像);面板标题与提示行文案随新定位换代(现行「查看本局钥石与永久强化进度」语义失效)。2026-10-16 用户令「不需要讨论的写进 08 并同步 06」——[08-Alpha版本标准](08-Alpha版本标准.md)「三 · 界面」状态面板行已换代(v1.8 起部分在役);元进度「解锁双入口框架」节与 camp 双入口框架句为设计权威文档反哺点待用户另批裁决。未排期,开工=用户发令或随 UI 批编入。 +**现状**:playnote 用户反馈:关卡界面中的"状态"面板不需要跨关解锁内容,只显示跟当前冒险有关的信息。现行实态(status_panel.gd 实查)=局内状态面板(2026-10-13 由「暂停层」改名)现为跨局进度镜像:钥石余额徽+「道具工坊 · 解锁态」段(实为秘宝匣 12 行解锁态概览)+「天赋树 · 已购概览」段——恰为用户要去掉的跨关解锁内容。范围=用户原话五件套,零待裁点:面板只留带的秘宝/已获专长/当前属性/现有 GP/钥石总量;秘宝匣解锁态 12 行概览与天赋树已购概览两段退役(跨局解锁概览由营地/生涯承载,局内不再镜像);面板标题与提示行文案随新定位换代(现行「查看本局钥石与永久强化进度」语义失效)。2026-10-16 用户令「不需要讨论的写进 08 并同步待办清单」——[08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「三 · 界面」状态面板行已换代(v1.8 起部分在役);元进度「解锁双入口框架」节与 camp 双入口框架句为设计权威文档反哺点待用户另批裁决。未排期,开工=用户发令或随 UI 批编入。 -**归属**:status_panel.gd(呈现层承载)+ [元进度](systems/跨局循环/元进度.md)「解锁双入口框架」节与 [camp](ux/camp.md) 双入口框架句(局内只读入口语义随瘦身穿改——设计权威文档反哺点,待用户裁决另批)+ [08-Alpha版本标准](08-Alpha版本标准.md)「三 · 界面」状态面板行(v1.8 起部分在役) +**归属**:status_panel.gd(呈现层承载)+ [元进度](design/gdd/systems/跨局循环/元进度.md)「解锁双入口框架」节与 [camp](design/gdd/ux/camp.md) 双入口框架句(局内只读入口语义随瘦身穿改——设计权威文档反哺点,待用户裁决另批)+ [08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「三 · 界面」状态面板行(v1.8 起部分在役) **状态**:待写卡 @@ -54,7 +54,7 @@ **现状**:案C 地图伤害账殿后批(git 7ef18ac,状态记录 371)改变每轮结算行为序——授予段不再兑付任何伤害(伤害形态单据暂存至战斗段末,段内序=主角先手→逐敌还手→地图账),既有全部 MC 行为锚与基线逐项比对锚所锚行为已不存在,**全数作废**;新段内序断言已入冒烟闸。按 sim-data MC 缓存层规则(无数值调整禁重跑),重锚不在改动批执行;重锚前一切 MC 旧读数只作历史存档,禁止与新行为逐项比对。M4 数值批卡 v1.2 已收该义务(F19:对拍锚按案C 新序重推导、T6 四带复算按新行为首采立新锚)。 -**缺口**:M4 数值批卡片已随 2026-10-16 删卡令退役;2026-10-18 用户裁=本条留 06、未设计未启动、不另行归属,未来数值标定窗口重开时重走设计段再写卡。 +**缺口**:M4 数值批卡片已随 2026-10-16 删卡令退役;2026-10-18 用户裁=本条留待办清单、未设计未启动、不另行归属,未来数值标定窗口重开时重走设计段再写卡。 **归属**:M-4 数值批(用户 2026-10-06 确认此为影响数值难度的重要变量)。 @@ -95,25 +95,25 @@ **现行实态**(`level.tres` 实查,三关各 5 张模板):**第一关五张模板全是单链排列变体**——7 个节点=战斗 ×4 + 奖励 + 休整 + Boss,战斗深度序单调保难度坡,**变化面只有奖励与休整两位的先后次序**,全链零分叉,玩家在选路上**没有任何选择**;第二/三关是网状图(10 节点,带 `next` 分支,最大层宽 4–5),有分叉,但用户仍判选择量不足。参考方向=Peglin(哥布林弹珠)的节点图移动与选路方式。 -**范围(重构面,非呈现面)**:节点数量、分叉度、选路自由度。连带三面——① [关卡节点图生成](systems/冒险循环/关卡节点图生成.md)(模板池与抽签机制,现行 15 张骨架=3 关 ×5 需重生成);② [level-map](ux/level-map.md)(选路枢纽三停点布局定稿版,图结构改则屏面随之改);③ [敌人系统](systems/战斗循环/敌人系统.md)(遭遇表按 `enemy.tres` 的 (level_index, node_depth) 坐标索引,节点数与编号一改,行集坐标与首遇教学位断言面全部随动)。 +**范围(重构面,非呈现面)**:节点数量、分叉度、选路自由度。连带三面——① [关卡节点图生成](design/gdd/systems/冒险循环/关卡节点图生成.md)(模板池与抽签机制,现行 15 张骨架=3 关 ×5 需重生成);② [level-map](design/gdd/ux/level-map.md)(选路枢纽三停点布局定稿版,图结构改则屏面随之改);③ [敌人系统](design/gdd/systems/战斗循环/敌人系统.md)(遭遇表按 `enemy.tres` 的 (level_index, node_depth) 坐标索引,节点数与编号一改,行集坐标与首遇教学位断言面全部随动)。 **量化要求补登(2026-10-16 playnote 用户补写)**:「需要统计一下第 123 关 path 的路径长度,路径长度需要递增,并且后续关卡的节点数增幅应该更大」(第 123 关=第 1/2/3 关)——重构设计讨论的验收方向两条:先实测三关路径长度基线,再定递增曲线与后续关增幅尺度。 -**前置(用户 2026-10-13 裁)**:**须先做文档设计讨论,不可直接开发**——参考调研+重构方案先行、过人闸后才可开卡。版本标准侧已登记为 Alpha 待做项,见 [08-Alpha版本标准](08-Alpha版本标准.md)「一 · 系统 · 冒险循环」。 +**前置(用户 2026-10-13 裁)**:**须先做文档设计讨论,不可直接开发**——参考调研+重构方案先行、过人闸后才可开卡。版本标准侧已登记为 Alpha 待做项,见 [08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「一 · 系统 · 冒险循环」。 **缺口**:还差参考调研+重构方案的设计讨论(含路径长度基线实测与递增曲线两条验收方向),过人闸后才能开卡。 -**归属**:[关卡节点地图](systems/冒险循环/关卡节点地图.md)(图结构与节点语义,主责)+ [关卡节点图生成](systems/冒险循环/关卡节点图生成.md)(模板池与抽签)+ [level-map](ux/level-map.md)(选路呈现)+ [敌人系统](systems/战斗循环/敌人系统.md)(遭遇行集坐标连带);版本标准侧已登记为 Alpha 待做项,见 [08-Alpha版本标准](08-Alpha版本标准.md)「一 · 系统 · 冒险循环」 +**归属**:[关卡节点地图](design/gdd/systems/冒险循环/关卡节点地图.md)(图结构与节点语义,主责)+ [关卡节点图生成](design/gdd/systems/冒险循环/关卡节点图生成.md)(模板池与抽签)+ [level-map](design/gdd/ux/level-map.md)(选路呈现)+ [敌人系统](design/gdd/systems/战斗循环/敌人系统.md)(遭遇行集坐标连带);版本标准侧已登记为 Alpha 待做项,见 [08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「一 · 系统 · 冒险循环」 **状态**:待文档设计 #### 天赋树实装批登记欠账余两件——AP 上限 clamp 与三选一刷新软上限(2026-10-12 登记,来源=批次移交,设计面=文档轨) -**现状**:迭代 21 天赋树实装批顺带入册欠账三条,2026-10-13 三件终态:① **AP 上限 clamp 缺位(缺陷)**——树「开局姿态」(每关首轮 AP+1)、AP 件、时沙同走 `action_economy.gd:239 _pending_ap_delta` 排队,轮始兑现仅下限钳制(`:254 maxi(0, …)`,无上限);**用户裁暂不设上限**——provisional 天花板亦不投,随未来数值标定窗口连同全部 AP 数值统一标定(M4 数值批已废)。② **三选一刷新软上限(设计问)**——停点内 GP 付费刷新倍率增长(×1.8/次曲线)×停点间基础价随进度递增,全程无软上限;**定性确认=设计问非缺陷,用户裁维持现状**,归未来数值标定窗口处理,不提前单开讨论。③ **Y(_attune_refresh_y)不入断点存档(可利用漏洞)**——已修复注销(2026-10-13 用户令提前单独开修:断点快照扩列 `attune_refresh_y`+续玩 `resume_adventure` 优先读断点〔缺键回退参数面=旧档行为零变化〕+单测两断言;冒烟 938/0+单测 24 套全绿)。①②留 06 待未来数值标定窗口(M4 数值批已废;2026-10-18 用户裁=不另行归属、未设计未启动)。 +**现状**:迭代 21 天赋树实装批顺带入册欠账三条,2026-10-13 三件终态:① **AP 上限 clamp 缺位(缺陷)**——树「开局姿态」(每关首轮 AP+1)、AP 件、时沙同走 `action_economy.gd:239 _pending_ap_delta` 排队,轮始兑现仅下限钳制(`:254 maxi(0, …)`,无上限);**用户裁暂不设上限**——provisional 天花板亦不投,随未来数值标定窗口连同全部 AP 数值统一标定(M4 数值批已废)。② **三选一刷新软上限(设计问)**——停点内 GP 付费刷新倍率增长(×1.8/次曲线)×停点间基础价随进度递增,全程无软上限;**定性确认=设计问非缺陷,用户裁维持现状**,归未来数值标定窗口处理,不提前单开讨论。③ **Y(_attune_refresh_y)不入断点存档(可利用漏洞)**——已修复注销(2026-10-13 用户令提前单独开修:断点快照扩列 `attune_refresh_y`+续玩 `resume_adventure` 优先读断点〔缺键回退参数面=旧档行为零变化〕+单测两断言;冒烟 938/0+单测 24 套全绿)。①②留待办清单待未来数值标定窗口(M4 数值批已废;2026-10-18 用户裁=不另行归属、未设计未启动)。 -**缺口**:还差未来数值标定窗口的标定执行(M4 数值批已废;2026-10-18 用户裁=本条留 06、未设计未启动、不另行归属)。 +**缺口**:还差未来数值标定窗口的标定执行(M4 数值批已废;2026-10-18 用户裁=本条留待办清单、未设计未启动、不另行归属)。 -**归属**:① [行动经济](systems/排雷循环/行动经济.md);② 行动经济+三选一/商店刷新经济(数值归未来数值标定窗口——M4 数值批已废);③ [存档序列化](systems/表现与支撑/存档序列化.md)(断点域)+ [冒险结构](systems/冒险循环/冒险结构.md)(续玩参数面)——③已修复注销 +**归属**:① [行动经济](design/gdd/systems/排雷循环/行动经济.md);② 行动经济+三选一/商店刷新经济(数值归未来数值标定窗口——M4 数值批已废);③ [存档序列化](design/gdd/systems/表现与支撑/存档序列化.md)(断点域)+ [冒险结构](design/gdd/systems/冒险循环/冒险结构.md)(续玩参数面)——③已修复注销 **状态**:待文档设计 @@ -131,7 +131,7 @@ **缺口**:还差 Beta 立项时的输入方案设计讨论——四个连带裁决点(光标反馈承载/键位映射/弹层焦点导航范围/键位自定义)先裁再开卡。 -**归属**:[排雷玩法](systems/排雷循环/排雷玩法.md)(动作语义与 8 向目标规则主责)+ [HUD 框架](systems/表现与支撑/HUD框架.md)(键盘光标与合法性反馈呈现)+ [设置与本地化](systems/表现与支撑/设置与本地化.md)(键位自定义,可选面) +**归属**:[排雷玩法](design/gdd/systems/排雷循环/排雷玩法.md)(动作语义与 8 向目标规则主责)+ [HUD 框架](design/gdd/systems/表现与支撑/HUD框架.md)(键盘光标与合法性反馈呈现)+ [设置与本地化](design/gdd/systems/表现与支撑/设置与本地化.md)(键位自定义,可选面) **状态**:待文档设计 @@ -141,7 +141,7 @@ **缺口**:还差敌人系统修订的设计讨论——情境触发器的条件形态、字段语义与首批触发器清单。 -**归属**:[敌人系统](systems/战斗循环/敌人系统.md)(P1) +**归属**:[敌人系统](design/gdd/systems/战斗循环/敌人系统.md)(P1) **状态**:待文档设计 @@ -151,7 +151,7 @@ **缺口**:还差敌人系统的变体池设计讨论——A2 案的池构成方案与精英专属池边界。 -**归属**:[敌人系统](systems/战斗循环/敌人系统.md)(P1) +**归属**:[敌人系统](design/gdd/systems/战斗循环/敌人系统.md)(P1) **状态**:待文档设计 @@ -161,7 +161,7 @@ **缺口**:还差备用闸的条款设计(N 值与作用域)——仅当实测读数支持时才启动讨论。 -**归属**:[敌人系统](systems/战斗循环/敌人系统.md) 与[难度曲线与Boss](systems/冒险循环/难度曲线与Boss.md)(P1) +**归属**:[敌人系统](design/gdd/systems/战斗循环/敌人系统.md) 与[难度曲线与Boss](design/gdd/systems/冒险循环/难度曲线与Boss.md)(P1) **状态**:待文档设计(备选) @@ -171,15 +171,15 @@ **缺口**:还差玩家侧技能知识系统的呈现设计讨论(HUD 承载形态与记谱口径),P2 后置面。 -**归属**:[HUD 框架](systems/表现与支撑/HUD框架.md) 与[敌人系统](systems/战斗循环/敌人系统.md)(P2) +**归属**:[HUD 框架](design/gdd/systems/表现与支撑/HUD框架.md) 与[敌人系统](design/gdd/systems/战斗循环/敌人系统.md)(P2) **状态**:待文档设计 #### 削弱档位的最终数值(2026-09-18 登记,来源=会话提及,设计面=文档轨) -**现状**:削弱取值域 [60,85] 与投值 −65 来自旧体系裁决;"封印标中必须比随便挖一格更值"的当量终值由[战斗结算](systems/战斗循环/战斗结算.md)与[地图战斗资源](systems/战斗循环/地图战斗资源.md)共裁。**语义侧已定案(2026-09-18 盘问会话,结构修复批落地)**:削弱叠层改续时——同名重复授予只刷新剩余结算数、层数恒 1(结构性消饱和);现行表值为临时值(provisional)。已入 M4 数值批卡 v1.2 件①(duration 终值投定+当量锚复算落文;含 β 带 [1.2,2.5] 可行子区间推算、flag_hit_premium=125 纳入同窗检算、`clear_dominance_audit.py` WEAKEN_PCT 常量随投值同步);2026-10-05 裁点已全裁并经同日联审二裁修订(P1甲/P2甲/P3甲/P4甲),跑批待 U0 用户发令、发起前须用户批准。 +**现状**:削弱取值域 [60,85] 与投值 −65 来自旧体系裁决;"封印标中必须比随便挖一格更值"的当量终值由[战斗结算](design/gdd/systems/战斗循环/战斗结算.md)与[地图战斗资源](design/gdd/systems/战斗循环/地图战斗资源.md)共裁。**语义侧已定案(2026-09-18 盘问会话,结构修复批落地)**:削弱叠层改续时——同名重复授予只刷新剩余结算数、层数恒 1(结构性消饱和);现行表值为临时值(provisional)。已入 M4 数值批卡 v1.2 件①(duration 终值投定+当量锚复算落文;含 β 带 [1.2,2.5] 可行子区间推算、flag_hit_premium=125 纳入同窗检算、`clear_dominance_audit.py` WEAKEN_PCT 常量随投值同步);2026-10-05 裁点已全裁并经同日联审二裁修订(P1甲/P2甲/P3甲/P4甲),跑批待 U0 用户发令、发起前须用户批准。 -**缺口**:M4 数值批卡片已随 2026-10-16 删卡令退役;2026-10-18 用户裁=本条留 06、未设计未启动、不另行归属,未来数值标定窗口重开时重走设计段再写卡。 +**缺口**:M4 数值批卡片已随 2026-10-16 删卡令退役;2026-10-18 用户裁=本条留待办清单、未设计未启动、不另行归属,未来数值标定窗口重开时重走设计段再写卡。 **归属**:战斗结算与地图战斗资源共裁(数值终值归状态层重设计批)——执行载体待未来数值标定窗口重开时重定(M4 数值批已废) @@ -207,19 +207,19 @@ #### 冒险前资源配比预设(构筑提案)(2026-09-18 登记,来源=会话提及,设计面=文档轨) -**现状**:构筑提案 2026-09-18 立项、八项裁决全裁(2026-10-04),设计闭合机制=[元进度](systems/跨局循环/元进度.md)「冒险开始参数面与覆盖值通道」(零新机制);2026-10-05 挂起——移出 roadmap 迭代 14,八项裁决与需求卡片冻结保留,重启须用户另行发令;全案与淘汰依据原载已退役提案(git 历史可考),裁决细节冻结在卡片。关联文档:[元进度](systems/跨局循环/元进度.md) v1.0(闭合凭据;现行 v1.21 已复核在役,2026-10-18 文档体检第 10 项);需求卡片 reports/需求卡片-冒险前资源配比预设批-2026-10-04.md(文件头挂冻结横幅)。 +**现状**:构筑提案 2026-09-18 立项、八项裁决全裁(2026-10-04),设计闭合机制=[元进度](design/gdd/systems/跨局循环/元进度.md)「冒险开始参数面与覆盖值通道」(零新机制);2026-10-05 挂起——移出 roadmap 迭代 14,八项裁决与需求卡片冻结保留,重启须用户另行发令;全案与淘汰依据原载已退役提案(git 历史可考),裁决细节冻结在卡片。关联文档:[元进度](design/gdd/systems/跨局循环/元进度.md) v1.0(闭合凭据;现行 v1.21 已复核在役,2026-10-18 文档体检第 10 项);需求卡片 reports/需求卡片-冒险前资源配比预设批-2026-10-04.md(文件头挂冻结横幅)。 -**归属**:[地图战斗资源](systems/战斗循环/地图战斗资源.md)修订批(基础配比的权重覆盖语义 + GDD 修订)与[元进度](systems/跨局循环/元进度.md)(解锁容量与注入生产者)共裁;呈现面归[HUD 框架](systems/表现与支撑/HUD框架.md)与[教学引导](systems/表现与支撑/教学引导.md)顺带。 +**归属**:[地图战斗资源](design/gdd/systems/战斗循环/地图战斗资源.md)修订批(基础配比的权重覆盖语义 + GDD 修订)与[元进度](design/gdd/systems/跨局循环/元进度.md)(解锁容量与注入生产者)共裁;呈现面归[HUD 框架](design/gdd/systems/表现与支撑/HUD框架.md)与[教学引导](design/gdd/systems/表现与支撑/教学引导.md)顺带。 **状态**:文档设计已闭合+已写卡(备选) #### GP 经济换算失衡——GP 袋面值与商店价格的换算关系复查(2026-10-07 登记,来源=审计发现,设计面=文档轨) -**现状**:道具三层审查的换算发现——小 GP 袋 20 ≈ 商店两三次首购(首购基价 4-5、A 链爬升前)≈ +2~4 点属性,而小攻击件只值 +1——「拿钱」在三选一面里经常比「拿数值」划算,且 GP 袋是池内最大户(23/98 张)进一步放大倾向。用户判「太离谱」。复查范围=GP 袋面值(20/50)× 商店基价(4/4/4/5)× 价格曲线(A=1.8 / b=1.1)× 战斗 GP 掉落(普通 3 / 精英 5 / Boss 8,关级加值 0/1/2)四处联动;目标=钱与属性件的换算效率回到设计意图(拿钱 vs 拿数值的取舍成立;GP 袋最大户地位要么有理由要么让位)。连带前提:L1 无商店节点使 GP 在第一关无消费口——「L1 商店编排」不另立条目、归本条复查范围(按 L1 是否补商店分两种情形各算一遍)。留 06 待未来数值标定窗口(M4 数值批已废;2026-10-18 用户裁=不另行归属、未设计未启动)。 +**现状**:道具三层审查的换算发现——小 GP 袋 20 ≈ 商店两三次首购(首购基价 4-5、A 链爬升前)≈ +2~4 点属性,而小攻击件只值 +1——「拿钱」在三选一面里经常比「拿数值」划算,且 GP 袋是池内最大户(23/98 张)进一步放大倾向。用户判「太离谱」。复查范围=GP 袋面值(20/50)× 商店基价(4/4/4/5)× 价格曲线(A=1.8 / b=1.1)× 战斗 GP 掉落(普通 3 / 精英 5 / Boss 8,关级加值 0/1/2)四处联动;目标=钱与属性件的换算效率回到设计意图(拿钱 vs 拿数值的取舍成立;GP 袋最大户地位要么有理由要么让位)。连带前提:L1 无商店节点使 GP 在第一关无消费口——「L1 商店编排」不另立条目、归本条复查范围(按 L1 是否补商店分两种情形各算一遍)。留待办清单待未来数值标定窗口(M4 数值批已废;2026-10-18 用户裁=不另行归属、未设计未启动)。 -**缺口**:还差四处联动的换算复查设计(含 L1 商店编排两种情形)——随未来数值标定窗口执行(M4 数值批已废,留 06 未设计未启动)。 +**缺口**:还差四处联动的换算复查设计(含 L1 商店编排两种情形)——随未来数值标定窗口执行(M4 数值批已废,留待办清单未设计未启动)。 -**归属**:[难度曲线与Boss](systems/冒险循环/难度曲线与Boss.md)调参批(未来数值标定窗口)+ 奇物池结构顺带 +**归属**:[难度曲线与Boss](design/gdd/systems/冒险循环/难度曲线与Boss.md)调参批(未来数值标定窗口)+ 奇物池结构顺带 **状态**:待文档设计 @@ -227,7 +227,7 @@ **现状**:迭代 10 奖励重构批(worktree 分支 m3-iter10-20261001)落地面产生三条后续义务——①钥石产出重标:渠道改「Boss/精英击杀掉落」(大奖励 keystone_per_level 退役、boss_keystone 重锚 provisional),现行元进度产出结构作废,标定义务重开;②通关率带重扫:通关回血 20%(血回满→部分回血,难度上压方向)+ 三选一件值/权重/次数上限 knob(AP 件=每场战斗首轮 +1 AP 强度敏感轴);③同调位读数源切换——**已清偿(2026-10-03 迭代 11 第①批 T7**:过渡键表/schema/断言三处退役,读取点归零,现行事实源=Attunement.slots 谓词表实时求值)。①②已入 M4 数值批卡 v1.2 件③(F7/F8;通关率带重扫与 T6 四带复算并账、一次跑批双认账),跑批待 U0 用户发令、发起前须用户批准。 -**缺口**:M4 数值批卡片已随 2026-10-16 删卡令退役;2026-10-18 用户裁=本条留 06、未设计未启动、不另行归属,未来数值标定窗口重开时重走设计段再写卡。 +**缺口**:M4 数值批卡片已随 2026-10-16 删卡令退役;2026-10-18 用户裁=本条留待办清单、未设计未启动、不另行归属,未来数值标定窗口重开时重走设计段再写卡。 **归属**:①元进度设计批 + 曲线调参批 ②曲线调参批(现行窗) ③秘宝同调实施批(已清偿 2026-10-03) @@ -235,21 +235,21 @@ #### 调参批数值点评登记(2026-10-01 登记,来源=批次移交,设计面=文档轨) -**现状**:格面资源八型批后顺带登记的数值点评——① 增伤型奖励/惩罚幅度 50/25 不对称是否有意;② 削弱型 65/25 同问(且 percent 套个位数取整偏粗);③ 回血奖励过薄(值 1、权重全池最低 2);④ 警觉/行动点修正两新词数值全部 provisional;⑤ 行动经济"满停一轮=一刷"节拍在 AP±1 修正下的对账——①-⑤五条已入 M4 数值批卡 v1.2 件②(F5,逐条裁决落文);⑥ **格面资源正负兑付倍率差回调(2026-10-07 用户裁)**——2026-10-01「踩雷必须痛」抬档(heal +2/−6、pierce/magic +2/−8 等,负向 3-4 倍于正向)系错误的加难杠杆:难度提升应走怪物性能路线而非抬地图惩罚,回调归未来数值标定窗口(M4 数值批已废),标错/开雷同档同罚维持不动(同批裁);⑥连同本条整体留 06 未设计未启动(2026-10-18 用户裁)。里程碑立规(2026-10-09):M4=Beta 阶段、M3 未由用户明令关闭前不排期。 +**现状**:格面资源八型批后顺带登记的数值点评——① 增伤型奖励/惩罚幅度 50/25 不对称是否有意;② 削弱型 65/25 同问(且 percent 套个位数取整偏粗);③ 回血奖励过薄(值 1、权重全池最低 2);④ 警觉/行动点修正两新词数值全部 provisional;⑤ 行动经济"满停一轮=一刷"节拍在 AP±1 修正下的对账——①-⑤五条已入 M4 数值批卡 v1.2 件②(F5,逐条裁决落文);⑥ **格面资源正负兑付倍率差回调(2026-10-07 用户裁)**——2026-10-01「踩雷必须痛」抬档(heal +2/−6、pierce/magic +2/−8 等,负向 3-4 倍于正向)系错误的加难杠杆:难度提升应走怪物性能路线而非抬地图惩罚,回调归未来数值标定窗口(M4 数值批已废),标错/开雷同档同罚维持不动(同批裁);⑥连同本条整体留待办清单未设计未启动(2026-10-18 用户裁)。里程碑立规(2026-10-09):M4=Beta 阶段、M3 未由用户明令关闭前不排期。 -**缺口**:M4 数值批卡片已随 2026-10-16 删卡令退役;2026-10-18 用户裁=本条留 06、未设计未启动、不另行归属,未来数值标定窗口重开时重走设计段再写卡。 +**缺口**:M4 数值批卡片已随 2026-10-16 删卡令退役;2026-10-18 用户裁=本条留待办清单、未设计未启动、不另行归属,未来数值标定窗口重开时重走设计段再写卡。 -**归属**:[难度曲线与Boss](systems/冒险循环/难度曲线与Boss.md)难度曲线调参批 +**归属**:[难度曲线与Boss](design/gdd/systems/冒险循环/难度曲线与Boss.md)难度曲线调参批 **状态**:待文档设计 #### 成长系数与关卡怪物难度提升的节奏(2026-10-16 登记,来源=playnote,设计面=文档轨) -**现状**:来源=playnote 用户反馈「一开始不能让角色的成长系数太高。比如在没经过升级之前,你的成长系数是跟不上关卡怪物难度提升的;但是后续能力解锁之后,成长系数才能匹配得上」。语义两读:**读法甲=节奏缺陷呈报**(前期成长跟不上怪物难度提升=要修的数值节奏问题,归属难度曲线与Boss+元进度解锁节奏的数值面);**读法乙=设计哲学陈述**(前期成长刻意克制、后期靠能力解锁追平=既定设计,应反哺难度曲线的设计语义)。2026-10-16 用户定性=数值校准类、与数值欠账同类任务,甲/乙两读随定性消解(无论现行节奏好坏,调它都是数值校准面的事);不进 [08-Alpha版本标准](08-Alpha版本标准.md)(数值调优义务 2026-10-16 v1.6 起不入版本标准);按里程碑立规属 Beta 阶段面,Alpha 不排期;留 06 数值欠账组,未设计未启动(2026-10-18 用户裁=不另行归属)。 +**现状**:来源=playnote 用户反馈「一开始不能让角色的成长系数太高。比如在没经过升级之前,你的成长系数是跟不上关卡怪物难度提升的;但是后续能力解锁之后,成长系数才能匹配得上」。语义两读:**读法甲=节奏缺陷呈报**(前期成长跟不上怪物难度提升=要修的数值节奏问题,归属难度曲线与Boss+元进度解锁节奏的数值面);**读法乙=设计哲学陈述**(前期成长刻意克制、后期靠能力解锁追平=既定设计,应反哺难度曲线的设计语义)。2026-10-16 用户定性=数值校准类、与数值欠账同类任务,甲/乙两读随定性消解(无论现行节奏好坏,调它都是数值校准面的事);不进 [08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)(数值调优义务 2026-10-16 v1.6 起不入版本标准);按里程碑立规属 Beta 阶段面,Alpha 不排期;留待办清单数值欠账组,未设计未启动(2026-10-18 用户裁=不另行归属)。 **缺口**:还差并入数值欠账组的归属落位(Beta 阶段数值校准窗口处理)。 -**归属**:[难度曲线与Boss](systems/冒险循环/难度曲线与Boss.md) + [元进度](systems/跨局循环/元进度.md)(成长系数语义面) +**归属**:[难度曲线与Boss](design/gdd/systems/冒险循环/难度曲线与Boss.md) + [元进度](design/gdd/systems/跨局循环/元进度.md)(成长系数语义面) **状态**:待文档设计 @@ -265,21 +265,21 @@ #### 袋装摇号(格面资源池结构备选——保底型增多后的重构方向)(2026-10-07 登记,来源=会话提及,设计面=文档轨) -**现状**:地图战斗资源池保底结构(四档概率 + 按型保底 + 档位保底上限,现行事实源=[地图战斗资源](systems/战斗循环/地图战斗资源.md)候选集合节)以「摇完整板校验补签」的补丁式实现起步——简单够用。备选正规形态=**袋装摇号**:装板时按各档配额数好牌再洗开发放,保底天然成立、分布精确;代价=摇号结构重写 + 偏运硬币/board_skew 两路权重投影须改为袋面投影。启用条件=保底登记型增多、补签逻辑复杂化时。来源=2026-10-07 地图层题四讨论,用户裁「先挂在 06」。 +**现状**:地图战斗资源池保底结构(四档概率 + 按型保底 + 档位保底上限,现行事实源=[地图战斗资源](design/gdd/systems/战斗循环/地图战斗资源.md)候选集合节)以「摇完整板校验补签」的补丁式实现起步——简单够用。备选正规形态=**袋装摇号**:装板时按各档配额数好牌再洗开发放,保底天然成立、分布精确;代价=摇号结构重写 + 偏运硬币/board_skew 两路权重投影须改为袋面投影。启用条件=保底登记型增多、补签逻辑复杂化时。来源=2026-10-07 地图层题四讨论,用户裁「先挂在待办清单」。 **缺口**:还差启用条件触发后的摇号结构重写设计讨论(含两路权重投影改袋面投影的方案)。 -**归属**:[地图战斗资源](systems/战斗循环/地图战斗资源.md)(重评归该层内容批或数值批窗口) +**归属**:[地图战斗资源](design/gdd/systems/战斗循环/地图战斗资源.md)(重评归该层内容批或数值批窗口) **状态**:待文档设计(备选) #### 战斗节点地图类型差异化——更多地图主题(2026-10-13 登记,来源=playnote,设计面=文档轨) -**现状**:来源=playnote 用户试玩记录「修改地图的奖励类型:战斗节点增加不同的地图类型,比如有些图踩雷受到更多的伤害,有些图标雷可以造成更多的伤害,有些图伤害会减半需要凑更多清图奖励(这些都是暂时的设定)」。**已实装的部分**:首发形态整图变异「贫矿脉」已于 2026-10-16 用户令屏蔽删行(Boss 图回落 region 变异,原 07⑪ 目检项随之转记失效)——本条剩余面不变:在此之上再做**更多地图主题**(踩雷伤害更高/标雷伤害更高/伤害减半需凑更多清图奖励)。**2026-10-13 用户裁定:排 Beta 版本,Alpha 不做**——已移入 [08-Alpha版本标准](08-Alpha版本标准.md)「六 · Alpha 不含」节。 +**现状**:来源=playnote 用户试玩记录「修改地图的奖励类型:战斗节点增加不同的地图类型,比如有些图踩雷受到更多的伤害,有些图标雷可以造成更多的伤害,有些图伤害会减半需要凑更多清图奖励(这些都是暂时的设定)」。**已实装的部分**:首发形态整图变异「贫矿脉」已于 2026-10-16 用户令屏蔽删行(Boss 图回落 region 变异,原体验验证清单⑪ 目检项随之转记失效)——本条剩余面不变:在此之上再做**更多地图主题**(踩雷伤害更高/标雷伤害更高/伤害减半需凑更多清图奖励)。**2026-10-13 用户裁定:排 Beta 版本,Alpha 不做**——已移入 [08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「六 · Alpha 不含」节。 **缺口**:还差 Beta 立项时的地图主题设计讨论——按本条原始想法重新评估(用户标注「这些都是暂时的设定」,到时需重订而非照抄)。 -**归属**:[棋盘生成](systems/排雷循环/棋盘生成.md)(board_biome 图主题词表)+ [地图战斗资源](systems/战斗循环/地图战斗资源.md)(图主题差异化插槽)+ [地形变异](systems/排雷循环/地形变异.md)(整图变异承载面) +**归属**:[棋盘生成](design/gdd/systems/排雷循环/棋盘生成.md)(board_biome 图主题词表)+ [地图战斗资源](design/gdd/systems/战斗循环/地图战斗资源.md)(图主题差异化插槽)+ [地形变异](design/gdd/systems/排雷循环/地形变异.md)(整图变异承载面) **状态**:待文档设计 @@ -289,15 +289,15 @@ **缺口**:还差真人批 k 系数到账后的加难紧迫性重判,再定正式扫描与杠杆标定设计。 -**归属**:难度曲线与Boss调参批,扫描执行与[棋盘生成](systems/排雷循环/棋盘生成.md)工具交付联动 +**归属**:难度曲线与Boss调参批,扫描执行与[棋盘生成](design/gdd/systems/排雷循环/棋盘生成.md)工具交付联动 **状态**:待文档设计(备选) #### 三方向各自的解锁清单与定价(2026-09-21 登记,来源=审计发现,设计面=文档轨) -**现状**:三方向(属性、遭遇、道具池)各自的解锁清单与定价:多少钥石换什么,各自怎么铺。来源=元进度 待设计问题清单第 2 条。部分完成(2026-09-21 元进度实现批再收窄;2026-09-23 换算率标定批再收窄)——**三柜台结构与 provisional 定价已落地**(属性锻造三档血+3/攻+1/甲+1、Boss 两档、工坊六件阈值 1/1/2/2/3/3 按总通关次数——全部读 `data/tables/meta.tres`);换算率三行已投值 6/9/1(冒险条件口径实测,护甲行强条目重测履行)。剩余面=定价数字与 Boss 两档终值——已入 M4 数值批卡 v1.2 件④(F11/F12;含 06 死文本两句全刷义务:「base 10 公比 150」滞后〔meta.tres 现行 forge base_price=20,2026-09-22 数值设计批对齿〕与「Boss 两档 L1 5/1·L2 8/2·L3 12/3」死数字句〔现值首杀 3/3/3 · 复杀 2/2/3〕,T4 判据按两句全刷执行)。 +**现状**:三方向(属性、遭遇、道具池)各自的解锁清单与定价:多少钥石换什么,各自怎么铺。来源=元进度 待设计问题清单第 2 条。部分完成(2026-09-21 元进度实现批再收窄;2026-09-23 换算率标定批再收窄)——**三柜台结构与 provisional 定价已落地**(属性锻造三档血+3/攻+1/甲+1、Boss 两档、工坊六件阈值 1/1/2/2/3/3 按总通关次数——全部读 `data/tables/meta.tres`);换算率三行已投值 6/9/1(冒险条件口径实测,护甲行强条目重测履行)。剩余面=定价数字与 Boss 两档终值——已入 M4 数值批卡 v1.2 件④(F11/F12;含待办清单死文本两句全刷义务:「base 10 公比 150」滞后〔meta.tres 现行 forge base_price=20,2026-09-22 数值设计批对齿〕与「Boss 两档 L1 5/1·L2 8/2·L3 12/3」死数字句〔现值首杀 3/3/3 · 复杀 2/2/3〕,T4 判据按两句全刷执行)。 -**缺口**:M4 数值批卡片已随 2026-10-16 删卡令退役;2026-10-18 用户裁=本条留 06、未设计未启动、不另行归属,未来数值标定窗口重开时重走设计段再写卡。 +**缺口**:M4 数值批卡片已随 2026-10-16 删卡令退役;2026-10-18 用户裁=本条留待办清单、未设计未启动、不另行归属,未来数值标定窗口重开时重走设计段再写卡。 **归属**:元进度设计批 @@ -313,7 +313,7 @@ #### 阔视野带效果表述与类型微光口径冲突(2026-10-20 登记,来源=批次移交,设计面=工程直入) -**现状**:迭代 30 卡①实现报告登记的存量冲突(报告已在这次收尾中退役,git 历史可考):[秘宝](systems/跨局循环/秘宝.md) 普通档表「阔视野带」行一句话写作「类型微光范围 8 格→12 格」,`game/data/tables/treasure_items.tres` 该行 `desc` 同口径;但 [HUD框架](systems/表现与支撑/HUD框架.md) 迷雾节配套拍板已定「类型微光不随视野扩大(贴身 8 格、微光锚=可挖域)」,实现面微光作用集恒为 `_diggable` 子集,该件实际效果是 `light_radius_bonus` 扩灯光区(迷雾视野 8→12),不扩类型微光。两处表述属提灯功能承接时期的遗留措辞。 +**现状**:迭代 30 卡①实现报告登记的存量冲突(报告已在这次收尾中退役,git 历史可考):[秘宝](design/gdd/systems/跨局循环/秘宝.md) 普通档表「阔视野带」行一句话写作「类型微光范围 8 格→12 格」,`game/data/tables/treasure_items.tres` 该行 `desc` 同口径;但 [HUD框架](design/gdd/systems/表现与支撑/HUD框架.md) 迷雾节配套拍板已定「类型微光不随视野扩大(贴身 8 格、微光锚=可挖域)」,实现面微光作用集恒为 `_diggable` 子集,该件实际效果是 `light_radius_bonus` 扩灯光区(迷雾视野 8→12),不扩类型微光。两处表述属提灯功能承接时期的遗留措辞。 **归属**:秘宝.md 普通档表该行 + treasure_items.tres 该行 desc(数据文本订正批;只改文字、不改机制) @@ -321,11 +321,11 @@ #### 第二 / 三关棋盘观感——亮度与对比度(2026-10-13 登记,来源=playnote,设计面=双轨) -**现状**:来源=playnote 用户试玩记录「UI 优化,第二第三关的棋盘看着太累了;不知道是因为亮度还是对比度的原因,看着非常费劲,非常不舒服」。2026-10-13 用户裁定:**这是需要做的**,且本就属版本标准的覆盖范围——[08-Alpha版本标准](08-Alpha版本标准.md)「五 · 表现」已新增「棋盘观感(第二 / 三关亮度与对比度)」行,标待做。**开工前须先定性(沿用既有裁决)**:是**素材轴**问题(棋盘瓦片与格面图标本身的明度与色相),还是 **UI 轴**问题(舞台底色与叠加层的对比关系)——两轴修法完全不同,定性错了等于白改一轮;该定性要求(原备忘 (e) 项)是本条的开工前置。2026-10-16 曾编入迭代 30 卡③(UI 呈现三卡批序位③),2026-10-17 用户裁定剔除回待设计(自身挂「素材轴/UI 轴」定性人闸+甲/乙〔recolor/远程生图重产〕素材裁点;若裁乙,其瓦片规格依赖战斗一屏样张批的目标规格清单产出)。v1.4 旧卡留 reports/需求卡片-二三关棋盘观感批-2026-10-16.md 作素材,非已写卡状态。与已完成注销的「呈现层残余 <4.5:1 文字位」分工:本条管**棋盘区域整体的观感**(亮度/对比度/费劲感,体感问题),彼条管**具体文字位的对比度读数**(机检可判硬指标),两条不同面不互相替代。 +**现状**:来源=playnote 用户试玩记录「UI 优化,第二第三关的棋盘看着太累了;不知道是因为亮度还是对比度的原因,看着非常费劲,非常不舒服」。2026-10-13 用户裁定:**这是需要做的**,且本就属版本标准的覆盖范围——[08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「五 · 表现」已新增「棋盘观感(第二 / 三关亮度与对比度)」行,标待做。**开工前须先定性(沿用既有裁决)**:是**素材轴**问题(棋盘瓦片与格面图标本身的明度与色相),还是 **UI 轴**问题(舞台底色与叠加层的对比关系)——两轴修法完全不同,定性错了等于白改一轮;该定性要求(原备忘 (e) 项)是本条的开工前置。2026-10-16 曾编入迭代 30 卡③(UI 呈现三卡批序位③),2026-10-17 用户裁定剔除回待设计(自身挂「素材轴/UI 轴」定性人闸+甲/乙〔recolor/远程生图重产〕素材裁点;若裁乙,其瓦片规格依赖战斗一屏样张批的目标规格清单产出)。v1.4 旧卡留 reports/需求卡片-二三关棋盘观感批-2026-10-16.md 作素材,非已写卡状态。与已完成注销的「呈现层残余 <4.5:1 文字位」分工:本条管**棋盘区域整体的观感**(亮度/对比度/费劲感,体感问题),彼条管**具体文字位的对比度读数**(机检可判硬指标),两条不同面不互相替代。 **缺口**:还差「素材轴 / UI 轴」定性设计讨论与甲/乙素材裁点裁决;素材轴若走重产,还依赖战斗一屏样张批的目标规格清单产出。 -**归属**:[HUD框架](systems/表现与支撑/HUD框架.md)(UI 轴:舞台底与叠加层)+ [美术圣经](../art/art-bible.md)(素材轴:瓦片与格面图标的明度色相)——定性前两方共裁 +**归属**:[HUD框架](design/gdd/systems/表现与支撑/HUD框架.md)(UI 轴:舞台底与叠加层)+ [美术圣经](design/art/art-bible.md)(素材轴:瓦片与格面图标的明度色相)——定性前两方共裁 **状态**:待文档设计+待美术设计 @@ -345,17 +345,17 @@ **缺口**:还差提灯点亮解禁候选的重议设计(升档批或用户点名触发时一并裁)。 -**归属**:[art-bible](../art/art-bible.md) §8.2 · 资产管线批 +**归属**:[art-bible](design/art/art-bible.md) §8.2 · 资产管线批 **状态**:待美术设计(备选) #### 立绘清晰度回退评估——是否改用高清图(2026-10-13 登记,来源=playnote,设计面=美术轨) -**现状**:来源=playnote 用户试玩记录「现在的立绘太丑了,像素化的粒度太低了,导致根本看不清立绘;看是否可以改回用较为高清的图片?还有一个问题是大小的问题……现在地精的图片看起来比熊地精还要大,这并不合理」。2026-10-13 用户裁定:与「第二 / 三关棋盘观感」同属**美术线更新**。**两个子问题现状不同**:子问题一=怪物大小比例不合理——**已兑现**(体量语义改生物体型〔character-design §5.2,弃强度线性映射〕+八敌逐键定档〔art-bible §8.2〕),剩余面=用户是否复核验收;子问题二=像素粒度过低/是否改回高清图——**方向已裁(2026-10-14 用户裁)**:「还是像素风格立绘,但是不需要像现在太过于像素」,定性为**精细手绘像素**(不是插画、不是 HD-2D、不回退高清图;裁决录=[美术审计-cursor会话存档](../research/美术审计-cursor会话存档-2026-10-14.md) §2.2;权威面 art-bible/character-design 口径节反哺另批),粒度问题已改派生管线(八敌源档 36–94 全过可读门槛:24 糊/32 可读/48 清楚)。[08-Alpha版本标准](08-Alpha版本标准.md) 未决项已随裁删除(2026-10-16 状态刷新批)。 +**现状**:来源=playnote 用户试玩记录「现在的立绘太丑了,像素化的粒度太低了,导致根本看不清立绘;看是否可以改回用较为高清的图片?还有一个问题是大小的问题……现在地精的图片看起来比熊地精还要大,这并不合理」。2026-10-13 用户裁定:与「第二 / 三关棋盘观感」同属**美术线更新**。**两个子问题现状不同**:子问题一=怪物大小比例不合理——**已兑现**(体量语义改生物体型〔character-design §5.2,弃强度线性映射〕+八敌逐键定档〔art-bible §8.2〕),剩余面=用户是否复核验收;子问题二=像素粒度过低/是否改回高清图——**方向已裁(2026-10-14 用户裁)**:「还是像素风格立绘,但是不需要像现在太过于像素」,定性为**精细手绘像素**(不是插画、不是 HD-2D、不回退高清图;裁决录=[美术审计-cursor会话存档](design/research/美术审计-cursor会话存档-2026-10-14.md) §2.2;权威面 art-bible/character-design 口径节反哺另批),粒度问题已改派生管线(八敌源档 36–94 全过可读门槛:24 糊/32 可读/48 清楚)。[08-Alpha版本标准](design/gdd/08-Alpha版本标准.md) 未决项已随裁删除(2026-10-16 状态刷新批)。 **缺口**:还差立绘按「精细手绘像素」新口径重产的设计——整屏方向稿与地面/立绘密度同批锁(与战斗一屏样张批联动)后才可出重产工单。 -**归属**:[角色设计](../art/character-design.md)(立绘规格与体量语义)+ [美术圣经](../art/art-bible.md)(像素管线与档位) +**归属**:[角色设计](design/art/character-design.md)(立绘规格与体量语义)+ [美术圣经](design/art/art-bible.md)(像素管线与档位) **状态**:待美术设计 @@ -365,7 +365,7 @@ **缺口**:还差重启时(重启闸=Alpha 定版批)的路线拍板——先拍三路线之一,再立帧数规格与资产工单。 -**归属**:[art-bible](../art/art-bible.md) §8.4 帧数规格 · 战斗表现批 +**归属**:[art-bible](design/art/art-bible.md) §8.4 帧数规格 · 战斗表现批 **状态**:待美术设计(备选) @@ -375,7 +375,7 @@ **缺口**:还差样张批终审触发的深描边例外复核——复核成立即注销,不成立则重启素材修订设计。 -**归属**:[character-design](../art/character-design.md) §5.1 · 样张批 +**归属**:[character-design](design/art/character-design.md) §5.1 · 样张批 **状态**:待美术设计(备选) @@ -383,7 +383,7 @@ **现状**:审计 P2-1——`artwork/ui-reuse-2026-09-23/` 独占 3043 个草稿(91%),vN 命名率 0%,冗余 41 文件,残留非素材文件(.url ×8 / .ogg ×6 / .ai ×2 / .swf ×1);根因=脚本链覆盖「生成→验证」但**缺「草稿整理」段**。整理涉及**批量文件移动/删除**,按用户惯例须先 dry-run 呈报清单、经确认再分批执行。执行窗口随实现批;开工=用户点名。 -**归属**:[art-bible](../art/art-bible.md) §8.3 归档纪律(原则已写入)· 资产管线批(工具+文件操作) +**归属**:[art-bible](design/art/art-bible.md) §8.3 归档纪律(原则已写入)· 资产管线批(工具+文件操作) **状态**:待写卡 @@ -393,7 +393,7 @@ **缺口**:还差整屏样张闸前整备批的启动——格式已定,差启动时点与分章执行。 -**归属**:[art-bible](../art/art-bible.md) 全文 · 样张批前置整备 +**归属**:[art-bible](design/art/art-bible.md) 全文 · 样张批前置整备 **状态**:待文档设计(备选) @@ -403,7 +403,7 @@ **缺口**:还差出图前置条件的达成——立绘定档与站桩重排实装批的 **C0 盒高账定案后再出图**(避免 B 区高度/构图二次返工);开工=用户点名。 -**归属**:[art-bible](../art/art-bible.md) §6.1(资产契约)+ §8.3 归档纪律 · 资产管线批;出图工单归 [art-assets-checklist](../art/art-assets-checklist.md) / 实装批任务书 +**归属**:[art-bible](design/art/art-bible.md) §6.1(资产契约)+ §8.3 归档纪律 · 资产管线批;出图工单归 [art-assets-checklist](design/art/art-assets-checklist.md) / 实装批任务书 **状态**:待美术设计 @@ -447,7 +447,7 @@ **缺口**:还差 Beta 批的两文档负责表对齐定稿。 -**归属**:教学引导与[设置与本地化](systems/表现与支撑/设置与本地化.md)共裁 +**归属**:教学引导与[设置与本地化](design/gdd/systems/表现与支撑/设置与本地化.md)共裁 **状态**:待文档设计 @@ -465,7 +465,7 @@ #### 「生涯」界面——冒险中数据回看的唯一承接处(2026-10-04 登记,来源=会话提及,设计面=文档轨) -**现状**:2026-10-04 用户裁决(UI 落码计划 P-C7)——冒险中不给数据回看:settlement_review_overlay(结算明细回看)与结算框「明细回看」钮在冒险中退役,战报带只留单行「上轮」;历史战报/结算明细的查看去向=新「生涯」界面(跨局汇总/历史冒险回看/图鉴承接)。来源=UI 重设计原型 v2 落码计划裁决记录(已退役,git 历史可查 §七)。**设计提纲已成文**:[systems/跨局循环/生涯.md](systems/跨局循环/生涯.md) v0.1 范围草案五节成文〔信息架构/承载内容清单/与既有界面关系/分期实装建议/待裁点〕,P0-P5 六裁点已全裁并写入文档〔P0甲 提纲落现行事实源 / P1甲 主菜单一级入口 / P2甲 每局一行摘要+cap 扩容 N+补用时埋点 / P3甲 敌人图鉴优先 / P4甲 局内不放入口+生涯零跳转 / P5甲 settlement_review 复活承接〕。**期一已落地**(2026-10-07 迭代 18 卡④实装批:生涯页六类九项+主菜单入口+终身计数域存档 v6,批末重闸全绿;实机人闸=07⑲ 生涯页目检节)。剩余面=期二(历史回看/图鉴)与期三实装+P6 营地最近冒险条带去留(新发现待裁点,随提纲评审一并裁)。**迭代 19 卡②遗留件(2026-10-08 登记)**:settlement_review_overlay.gd 现态考证=未接线遗留件(全仓零引用,M9 结算框改版「明细回看」钮退役后遗留)——处置两途:①随生涯实装批按 P5 甲复活承接(重接线入生涯);②确认不再需要则正式退役删除文件;二选一归生涯实装批/用户裁。 +**现状**:2026-10-04 用户裁决(UI 落码计划 P-C7)——冒险中不给数据回看:settlement_review_overlay(结算明细回看)与结算框「明细回看」钮在冒险中退役,战报带只留单行「上轮」;历史战报/结算明细的查看去向=新「生涯」界面(跨局汇总/历史冒险回看/图鉴承接)。来源=UI 重设计原型 v2 落码计划裁决记录(已退役,git 历史可查 §七)。**设计提纲已成文**:[systems/跨局循环/生涯.md](design/gdd/systems/跨局循环/生涯.md) v0.1 范围草案五节成文〔信息架构/承载内容清单/与既有界面关系/分期实装建议/待裁点〕,P0-P5 六裁点已全裁并写入文档〔P0甲 提纲落现行事实源 / P1甲 主菜单一级入口 / P2甲 每局一行摘要+cap 扩容 N+补用时埋点 / P3甲 敌人图鉴优先 / P4甲 局内不放入口+生涯零跳转 / P5甲 settlement_review 复活承接〕。**期一已落地**(2026-10-07 迭代 18 卡④实装批:生涯页六类九项+主菜单入口+终身计数域存档 v6,批末重闸全绿;实机人闸=体验验证清单⑲ 生涯页目检节)。剩余面=期二(历史回看/图鉴)与期三实装+P6 营地最近冒险条带去留(新发现待裁点,随提纲评审一并裁)。**迭代 19 卡②遗留件(2026-10-08 登记)**:settlement_review_overlay.gd 现态考证=未接线遗留件(全仓零引用,M9 结算框改版「明细回看」钮退役后遗留)——处置两途:①随生涯实装批按 P5 甲复活承接(重接线入生涯);②确认不再需要则正式退役删除文件;二选一归生涯实装批/用户裁。 **缺口**:还差提纲用户评审收尾与 P6 营地最近冒险条带去留裁决——裁完才能立期二/期三实装卡(期一已交付,期二/三未预占排期)。 @@ -477,7 +477,7 @@ #### 商店独立刷新机制——两参数待调参 + 机制文档回写(2026-10-04 登记,来源=会话提及,设计面=文档轨) -**现状**:2026-10-04 用户裁决(P-C2+Q2 二次裁)推翻关卡节点地图 v1.5「无独立刷新、重抽绑购买」口径,定案=**基础免费 0 次 + GP 刷新(ceil(20×1.8^已付费刷) provisional)+ 池源同源(共享池,与三选一同一账本)**;**天赋/营地侧「刷新次数」增益=用户既有意向(口头裁决,曾因未写入文档丢失——Q2 追认),后续由用户调整添加,实现面预留 free_count=天赋增益位**。未定:天赋增益的具体形态与数值。**机制已落码**(SR-1 随 UI 落码批收官,2026-10-04/05);**三选一同款付费刷新已落码**(2026-10-06 用户令——「三选一对齐商店,得有刷新」:免费双源〔刷新件 X/冒险池 Y〕用尽后 GP 付费刷新,同旋钮同曲线同钱包;机制登记归[秘宝](systems/跨局循环/秘宝.md)「三选一刷新双源」节)。剩余待办:①调参(shop_refresh_free/曲线两参数 provisional,归未来数值标定窗口顺带——M4 数值批已废);②天赋增益形态与数值(设计未定);③机制文档回写核对(冒险结构共享池账本节/关卡节点地图商店行 v1.6 已记,本条完成时核对三处同步)。 +**现状**:2026-10-04 用户裁决(P-C2+Q2 二次裁)推翻关卡节点地图 v1.5「无独立刷新、重抽绑购买」口径,定案=**基础免费 0 次 + GP 刷新(ceil(20×1.8^已付费刷) provisional)+ 池源同源(共享池,与三选一同一账本)**;**天赋/营地侧「刷新次数」增益=用户既有意向(口头裁决,曾因未写入文档丢失——Q2 追认),后续由用户调整添加,实现面预留 free_count=天赋增益位**。未定:天赋增益的具体形态与数值。**机制已落码**(SR-1 随 UI 落码批收官,2026-10-04/05);**三选一同款付费刷新已落码**(2026-10-06 用户令——「三选一对齐商店,得有刷新」:免费双源〔刷新件 X/冒险池 Y〕用尽后 GP 付费刷新,同旋钮同曲线同钱包;机制登记归[秘宝](design/gdd/systems/跨局循环/秘宝.md)「三选一刷新双源」节)。剩余待办:①调参(shop_refresh_free/曲线两参数 provisional,归未来数值标定窗口顺带——M4 数值批已废);②天赋增益形态与数值(设计未定);③机制文档回写核对(冒险结构共享池账本节/关卡节点地图商店行 v1.6 已记,本条完成时核对三处同步)。 **缺口**:还差天赋增益形态与数值的设计讨论(用户调整时裁)与 M4 窗口的两参数标定;③回写核对随完成时点履行。 @@ -495,7 +495,7 @@ #### qa/ 实现报告收尾·孤儿遗留七项(2026-10-14 登记,来源=批次移交,设计面=工程直入) -**现状**:qa 收尾批核查 iter19 系列出口报告遗留移交项时发现**不在 06 在册**的七项(acceptance-package §三.2/card0 §5.3/followup §七.3/uibackfill §6.2-4/verify §6.1/3/7)。已结案的(tree_rules 受理闭环、X/Y 双源、S1 七项违例修复、提灯目检项、tests.yml 休眠等)已在各报告标注结案证据,不入本条。七项均为挂号备查/顺路件,无排期承诺: +**现状**:qa 收尾批核查 iter19 系列出口报告遗留移交项时发现**不在待办清单在册**的七项(acceptance-package §三.2/card0 §5.3/followup §七.3/uibackfill §6.2-4/verify §6.1/3/7)。已结案的(tree_rules 受理闭环、X/Y 双源、S1 七项违例修复、提灯目检项、tests.yml 休眠等)已在各报告标注结案证据,不入本条。七项均为挂号备查/顺路件,无排期承诺: 1. **design/diagrams 越界**(熵增闸存量红,archify 架构图批 00712d5 旧债):脚本自文「新分类先过用户拍板再改两处白名单」。修案二选一——甲=用户拍板 `design/diagrams` 入 DESIGN_SUBDIRS 白名单(archify 总图批产物归位);乙=迁出 design/ 归位合法区。**归属**:熵增闸白名单(AGENTS.md Project Layout+脚本白名单两处) 2. **开场行后缀认加算区**(iter19 卡⓪遗留):现口径=「局外加成存在才带」后缀(需求卡片字面执行);局内有加算区 flat 但无局外加成时,开场行数字含加成却不带注记——是否扩展认加算区归设计批裁定。**归属**:冒险结构/战斗开场参数面 @@ -521,7 +521,7 @@ #### 技术债观察登记——长函数余量与 lambda 连接防回归(2026-10-15 登记,来源=批次移交,设计面=工程直入) -**现状**:迭代 27 需求卡片两项「登记 06 观察」义务批内漏登,卡片核对时补登——①**长函数 17 个**中非结算段的装配/校验函数(`level_map_screen.gd` 选路装配 155 行/`camp_overlay_view.gd` 152 行/`debug_overlay.gd` 114 行/`treasure_item_table.gd` schema 校验群等;`main._build_ui` 已随场景拆分自然解体、`_settle`/`_resolve_hero_attack` 已随波二拆段=17 中 3 件已消解,余 14 件);②**lambda 连接 76 处**(presentation 6/smoke 62/tests 8——实读无泄漏,登记防回归)。长函数拆分无独立需求驱动不动;lambda 连接数若有审计工具化需求归类型闸后续。 +**现状**:迭代 27 需求卡片两项「登记待办清单观察」义务批内漏登,卡片核对时补登——①**长函数 17 个**中非结算段的装配/校验函数(`level_map_screen.gd` 选路装配 155 行/`camp_overlay_view.gd` 152 行/`debug_overlay.gd` 114 行/`treasure_item_table.gd` schema 校验群等;`main._build_ui` 已随场景拆分自然解体、`_settle`/`_resolve_hero_attack` 已随波二拆段=17 中 3 件已消解,余 14 件);②**lambda 连接 76 处**(presentation 6/smoke 62/tests 8——实读无泄漏,登记防回归)。长函数拆分无独立需求驱动不动;lambda 连接数若有审计工具化需求归类型闸后续。 **归属**:工程债观察备忘(不阻塞,不排期;新增此类代码沿现役规范评审盯) @@ -563,7 +563,7 @@ #### 需求卡片入库纪律未登记——502 批遗留的悬空待办(2026-10-18 登记,来源=批次移交,设计面=反哺点) -**现状**:2026-10-16 迭代 29 编入批(提交 `21c83f5`)认定「需求卡片写进了 roadmap 却没在 06 登记」属流程漏洞,需要补一条卡片入库纪律。该条至今在 06 清单内查无(2026-10-17 与 2026-10-18 两次全文检索零命中)。唯一记过它的地方是根目录状态文件未决面第 31 行,该文件已于 2026-10-18 用户裁废除,故改记本条防遗忘。待裁:这条纪律要不要立;立则写进归属所指的 process-conventions。 +**现状**:2026-10-16 迭代 29 编入批(提交 `21c83f5`)认定「需求卡片写进了 roadmap 却没在待办清单登记」属流程漏洞,需要补一条卡片入库纪律。该条至今在待办清单清单内查无(2026-10-17 与 2026-10-18 两次全文检索零命中)。唯一记过它的地方是根目录状态文件未决面第 31 行,该文件已于 2026-10-18 用户裁废除,故改记本条防遗忘。待裁:这条纪律要不要立;立则写进归属所指的 process-conventions。 **归属**:design/engineering/process-conventions.md 五段流水线的登记段 @@ -688,10 +688,10 @@ **含「雷」字面**(违反术语表「对外命名纪律」——「雷」及相关字面禁入对外命名,适用范围含 UI 文案)=`完美排雷` 21 处,其中 **3 处为玩家可见文案**:`core/battle_orchestrator.gd:925` `"完美排雷!清图奖励 ×2"`、`presentation/views/board_fx_view.gd:102` `_show_banner("完美排雷 ×2")`、`presentation/views/battle_log_view.gd:194` `"(本板完美排雷已破——归因此封印)"`(末条 `design/qa/文案审查报告-2026-10-18.md:150` 已判病句,至今未修)。 **根因**:迭代 31 卡① 完成判据 V4 只覆盖「金币/插旗/雷格/惩罚格」四词(+旗族),`排雷`/`雷`族未入完成判据;且机检闸 `tools/doc_term_audit.py` 的 `DEFAULT_DIRS = ["design/gdd"]`,**代码注释面从未进闸**——不清根则同类残留持续复发。 **裁定(2026-10-19 用户)**:完美排雷**全库统一**换代为「完美封印」,含代码内部注释。本裁**推翻** `需求卡片-凭证件裁削批`:108「内部开发用语按 v3.15 纪律保留」半句,该卡片条款订正归**文档轨批**,代码批照本裁执行。 -**移交(不属本批)**:`game/data/tables/shop.tres:86` display_name「奇物门票」、`game/presentation/curio_interact_controller.gd:165-166`「开一次奇物三选一」——两处属 奇物/专长 归类表述,与 06「2026-10-18 冒记案遗留待裁两项」第①项同源,交文档侧先定性,定后另走传导批。 +**移交(不属本批)**:`game/data/tables/shop.tres:86` display_name「奇物门票」、`game/presentation/curio_interact_controller.gd:165-166`「开一次奇物三选一」——两处属 奇物/专长 归类表述,与待办清单「2026-10-18 冒记案遗留待裁两项」第①项同源,交文档侧先定性,定后另走传导批。 **扫描中查出的真缺陷(N7)**:`core/settlement/grant_segment.gd:300` 用 RAW 误标计数判「完美封印已破」,而 `core/battle_orchestrator.gd:1299` 的真正谓词用**有效误标**(总数 − 豁免数);且豁免累加(:314)排在 `_emit_row`(:302)之后。⇒ 装备「完美保险」时日志打印「已破」,实际加倍奖励仍发,日志与真值矛盾。2026-10-20 用户裁=并入本批修(判据改有效误标+`_emit_row` 后移至豁免循环之后+文案两态;修法 v1.2 定型——上移豁免累加需重复调用 `_fx_emit` 会重复消费限次,已核实不可行)。 -**不做(待用户另裁)**:术语表 A 表词一族、doc-conventions 第 4 节流程动词一族、简明技术中文(STC)通用禁用词一族——三族的逐词计数与清单见卡片 §4「不做」表(本行不复制词面:06 正文引述禁词会自指引爆 doc_term 补充通道,判红)。 +**不做(待用户另裁)**:术语表 A 表词一族、doc-conventions 第 4 节流程动词一族、简明技术中文(STC)通用禁用词一族——三族的逐词计数与清单见卡片 §4「不做」表(本行不复制词面:待办清单正文引述禁词会自指引爆 doc_term 补充通道,判红)。 需求卡片:reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md(v1.3)。 From 84daa61a908c48b41c94209250a991c957688feb Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 00:36:54 +0800 Subject: [PATCH 43/59] =?UTF-8?q?rules(AGENTS.md):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=A1=AC=E6=80=A7=E7=BA=A2=E7=BA=BF=E3=80=8C=E8=A7=84=E5=88=99?= =?UTF-8?q?=E8=AF=84=E4=BC=B0=E3=80=8D=E4=B8=80=E6=9D=A1=E2=80=94=E2=80=94?= =?UTF-8?q?=E6=B2=A1=E5=9C=A8=E7=9C=9F=E5=AE=9E=E4=BB=BB=E5=8A=A1=E4=B8=8A?= =?UTF-8?q?=E8=AF=84=E4=BC=B0=E8=BF=87=E7=9A=84=E8=A7=84=E5=88=99=E4=BF=AE?= =?UTF-8?q?=E8=AE=A2=EF=BC=8C=E4=B8=8D=E7=AE=97=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 紧跟变异验证条(机器判据的姊妹纪律,管行为条文这半边)。用户特许本条自身免评估合入(2026-10-21)——按新条口径如实记:本条已修订,评估未做。 --- AGENTS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AGENTS.md b/AGENTS.md index f501d554..b695f3a9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -61,6 +61,7 @@ - MC/模拟:无数值改动零跑;档位硬闸见 `sim-data/README.md`「MC 采集档位表」,一档只能由用户发起 - 闸机轮次纪律:新码先孤立验证 → 出红只跑红件最小单元 → 长批先最小参数试车 → 开工扫坑册(process-conventions §6) - 变异验证——新增/改写验收函数必须变异变红才算验收成立;无变异红记录只写「已实现,拦截能力未证」(test-conventions §6) +- 规则评估——没在真实任务上评估过的规则修订,不算完成。 - 中间产物吸收即死——结论先吸收进权威文档、未决先迁待办清单,文件即删且永不提交(doc-conventions 第 11 节) - **禁写变更记录**——文档与代码文件内一律禁设「版本历史/修订记录/变更记录/修改记录/更新记录/更新日志」节或表格,禁写「本版改了哪些条款」式逐版本叙述与 `# 2026-xx-xx 缺陷修批——` 式行内修订注记;沿革只进 git commit log。版本号可作文档现行身份标记留在文首状态行与正文引用中(doc-conventions 第 5 节,机检闸 gdd_lint R4 反转拦截) - 用语红线——一切对用户输出禁自造黑话,需要作者解释的词必须展开成完整白话句(doc-conventions 第 4 节三形态表) From f100e1927518b45927454970d6f5cb69cfcbabba Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 00:53:42 +0800 Subject: [PATCH 44/59] =?UTF-8?q?docs(gdd):=20=E5=88=A0=E9=99=A4=E3=80=8C?= =?UTF-8?q?=E5=85=B3=E5=8D=A1=E8=8A=82=E7=82=B9=E5=9B=BE=E7=94=9F=E6=88=90?= =?UTF-8?q?=E3=80=8D=E6=97=A7=E7=89=88=E6=96=87=E6=A1=A3=EF=BC=88=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BB=A4=202026-10-21=EF=BC=89=E2=80=94=E2=80=94?= =?UTF-8?q?=E5=87=BA=E5=BA=A6=E2=89=A42/=E5=B1=82=E5=AE=BD=E2=89=A44=20?= =?UTF-8?q?=E6=97=A7=E8=A7=84=E9=9A=8F=E6=A1=A3=E9=80=80=E5=9C=BA=EF=BC=9B?= =?UTF-8?q?=E5=BC=95=E7=94=A8=E9=9D=A2=E5=85=AB=E5=A4=84=E6=94=B9=E6=8C=87?= =?UTF-8?q?=E8=B7=AF=E6=96=87=E6=9C=AC=EF=BC=8802=20=E7=B4=A2=E5=BC=95?= =?UTF-8?q?=E8=A1=8C/08=20=E8=A1=8C/=E5=85=B3=E5=8D=A1=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E5=9C=B0=E5=9B=BE/=E5=86=92=E9=99=A9=E7=BB=93=E6=9E=84/level-m?= =?UTF-8?q?ap/=E5=BE=85=E5=8A=9E=E6=B8=85=E5=8D=95=E4=B8=A4=E5=A4=84/Alpha?= =?UTF-8?q?=E6=A2=B3=E7=90=86=EF=BC=89=EF=BC=9B=E5=BD=92=E6=A1=A3=E5=89=AF?= =?UTF-8?q?=E6=9C=AC=E8=90=BD=E4=B8=BB=E5=8C=BA=20archive/=EF=BC=8C?= =?UTF-8?q?=E9=9A=8F=E5=85=B3=E5=8D=A1=E8=8A=82=E7=82=B9=E5=9B=BE=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E6=89=B9=E9=87=8D=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/gdd/02-系统清单.md | 1 - design/gdd/08-Alpha版本标准.md | 2 +- design/gdd/systems/冒险循环/关卡节点图生成.md | 214 ------------------ design/gdd/systems/冒险循环/关卡节点地图.md | 2 +- design/gdd/systems/冒险循环/冒险结构.md | 2 +- design/gdd/ux/level-map.md | 2 +- .../Alpha未完成事项梳理-2026-10-13.md | 2 +- 待办清单.md | 4 +- 8 files changed, 7 insertions(+), 222 deletions(-) delete mode 100644 design/gdd/systems/冒险循环/关卡节点图生成.md diff --git a/design/gdd/02-系统清单.md b/design/gdd/02-系统清单.md index f0b61b3e..7c669554 100644 --- a/design/gdd/02-系统清单.md +++ b/design/gdd/02-系统清单.md @@ -43,7 +43,6 @@ | 文件 | 一句话概要 | 状态 | |---|---|---| | `关卡节点地图.md` | 单关内的节点图选路与推进 | 已定稿 | -| `关卡节点图生成.md` | 单关节点图的逐局随机来源:图模板池、抽签与实例化(实施排队统一流裁决后) | 设计草案·拍板点全部已写入 | | `冒险结构.md` | 整局冒险的关卡序列、失败与大奖励 | 已定稿·自旧体系迁移 | | `难度曲线与Boss.md` | 难度曲线、期望值带与 Boss 设计 | 已定稿·自旧体系迁移 | | `奇物.md` | 一次冒险内各渠道给予玩家的增益总称(专长=触发器句式的机制件 / 属性值提升 / 补给=给系统资源加一笔的转换源凭证 × 三条渠道:奖励节点 / 商店 / 关底 Boss 击败) | 已实现·迭代 20 专长实装批落地(29 行=基础 27+迁入 2,流派机制退役;池结构案D 四级 104,通关兑付=专长三选一按档配比加权) | diff --git a/design/gdd/08-Alpha版本标准.md b/design/gdd/08-Alpha版本标准.md index 860640da..8e723532 100644 --- a/design/gdd/08-Alpha版本标准.md +++ b/design/gdd/08-Alpha版本标准.md @@ -46,7 +46,7 @@ | 冒险结构 | [冒险结构](systems/冒险循环/冒险结构.md) | 在役 | | 关卡节点地图 | [关卡节点地图](systems/冒险循环/关卡节点地图.md) | 在役(待重构,见下一条) | | 关卡节点图重构(增加可选节点) | [关卡节点地图](systems/冒险循环/关卡节点地图.md) | 待做(须先做文档设计,不可直接开发) | -| 关卡节点图生成 | [关卡节点图生成](systems/冒险循环/关卡节点图生成.md) | 在役 | +| 关卡节点图生成 | 旧版文档已删,随关卡节点图重构批重写 | 在役(待重构,与上一条同批) | | 难度曲线与 Boss | [难度曲线与Boss](systems/冒险循环/难度曲线与Boss.md) | 在役 | | 奇物 | [奇物](systems/冒险循环/奇物.md) | 在役 | diff --git a/design/gdd/systems/冒险循环/关卡节点图生成.md b/design/gdd/systems/冒险循环/关卡节点图生成.md deleted file mode 100644 index caad54b6..00000000 --- a/design/gdd/systems/冒险循环/关卡节点图生成.md +++ /dev/null @@ -1,214 +0,0 @@ -# 关卡节点图生成 - -> 一句话:单关节点图怎么从固定配置变成逐局随机——图模板池、抽签与实例化 -> 状态:**v0.5 台阶一已实施**(迭代 5 T5,2026-09-28 落 master 前挂 worktree m3-iter5-20260928——15 张骨架+node_map 扩签+首次冒险固定脚本+池内全模板校验+MC 分层出数,冒烟 576/0;文档本节规则与实现一致性以本批落地为准,台阶二/三仍后置) -> 旧版参考:无(旧体系未单独成文;事项自 2026-09-20 立项,池重生成已落地〔2026-09-29 返工批,二轮目检 15/15 过〕,原待办清单条目已完成移除) - -## 设计目的 - -现行每关的节点图是关卡表里写死的一行行集——玩家每一局走的是完全相同的图。对照参照游戏:杀戮尖塔每层抽一张新地图,哈迪斯的房间编排逐局变化——布局变化本身就是"再来一局"的驱动力的一部分,而本作这块目前是零。 - -本文立项把单关节点图从固定配置升级为逐局随机。边界先说死:本文只管**图从哪里来**;图怎么走、走到每个节点发生什么、图合法性怎么校验,全部仍是[关卡节点地图](关卡节点地图.md)的现行规则,本设计对它们零改动——生成侧的职责止于"生产一张合法的图",生产出来的图进的是既有校验、既有行进、既有兑付。 - -## 系统范围 - -边界这样划:图模板与模板池是内容资产(与敌人表行、棋盘参数同级的配置内容),抽签是玩法随机(消费主种子派生流),实例化的产物就是关卡表行集——行集内容的责任方仍是[冒险结构](冒险结构.md),本文管的是行集**怎么被生产出来**。 - -负责: - -| 负责 | 说明 | -|---|---| -| 图模板的结构定义 | 一张模板有哪些组成部分、满足什么条件才算一张合法模板 | -| 模板池与关卡表接线 | 每关从哪个池抽、池怎么随关卡表配置 | -| 抽签时机与随机流 | 什么时候抽、消费哪条封闭流、可复现域怎么覆盖 | -| 实例化与校验交接 | 模板落成行集,交给既有的图合法性校验 | -| 台阶路线与测量对账 | 三级台阶的推进条件;模拟读数不被随机污染的口径 | - -不负责: - -| 不负责 | 归谁 | -|---|---| -| 节点图怎么走、选路、兑付触发、收束点 | [关卡节点地图](关卡节点地图.md)(现行规则零改动) | -| 图合法性校验的检查项与算法 | [关卡节点地图](关卡节点地图.md)(LevelTable.validate 现行——生成侧只是它的上游供给方) | -| 池里放几张模板、每张模板里放什么遭遇数值 | [冒险结构](冒险结构.md)(行集内容责任方)与[难度曲线与Boss](难度曲线与Boss.md)(数值所有权) | -| 战斗节点内部的敌人配置与初始化 | 战斗循环(节点编号寻址口径零改动) | -| 节点图的画面呈现 | [HUD框架](../表现与支撑/HUD框架.md)(节点态照旧读图,零新呈现语义) | - -## 在核心循环中的位置 - -``` -冒险结构 ──开始关卡──▶ 关卡节点图生成(抽模板 → 实例化行集)──行集──▶ 关卡节点地图(校验 → 选路行进) -``` - -[核心循环](../../01-核心循环.md)里"关卡:节点链逐节点推进"这一段之前,多了一步"这一关的图是哪张"的抽签——本系统就站在这一步。它向上接冒险结构的开始关卡请求,向下把实例化好的行集交给关卡节点地图;生成之后的一切(校验、行进、兑付、收束)与本系统无关。 - -## 核心规则 - -### 概念三件套:图模板、模板池、图模板抽签 - -**人话阶段**:本系统只有三个概念,弄清它们谁包含谁,整个系统就读懂了。 - -**图模板**(本文含义:一张手工编写的合法节点图骨架——一个节点集合〔每个节点带类型标注与关卡内唯一编号〕加一个连线集合)是内容资产,不是运行期生成物。**实例化**(本文含义:把模板原样照抄落成该关的行集——节点集合与连线进关卡表行,零变换)之后,它就是关卡节点地图要加载的那张图。 - -| 概念 | 一句话定义 | 归谁 | -|---|---|---| -| 图模板 | 手工编写的合法节点图骨架;实例化即行集 | 本文(结构规则);内容归冒险结构 | -| 模板池 | 关卡表逐关行配置的同关可抽模板集合,池大小 N(N≥1) | 本文(规则);配置承载归数据配置 | -| 图模板抽签 | 关卡开始时从池中均匀抽一张 | 本文(时机与流);流基础设施归数据配置 | - -模板池挂在关卡表逐关行上:行集从"单一节点集合"扩为"模板池"。**N=1 的池里只有现行那张图,逐局抽签退化回固定图**——这是**回滚档**(本文含义:任何一关把池缩回一张模板,该关行为就与今日固定配置逐位等价的保险形态)。整个设计因此可增量落地:先全关 N=1,再逐关扩池。 - -抽签消费主种子派生的统一随机流,走扩签通道新立用途标签 `node_map`(统一流口径已定——2026-09-27 两轮复裁落地;标签不参与派生、只进事件日志)。 - -**出度上限与层宽(2026-10-01 用户拍板 T17 目检)**:单节点出边数(出度)**最大为 2**——加载校验第七检(`fanout_violation` 加载致命)。规则连带(数学约束):出度 ≤2 + 入口唯一下,BFS 层宽上限 = **4**(层宽序列上限 1,2,4;2026-09-29 旧规则「层宽上限 5」与出度约束不相容,随本拍板废止)。现行池 = `tools/t17_fanout2_rebuild.py` 按两规则重建(五骨架:宽廊双干〔现行〕/三干中廊/宽廊斜岔/三干宽门/窄廊短支——层宽序列 1-2-4-1-1 / 1-2-3-2-1 / 1-2-2-2-1,最大层宽 4 应用足)。 - -**内容纪律**:每张新模板等于一个小内容批——模板里每个战斗与 Boss 节点都必须在敌人与棋盘生成的数值表里有精确行,义务从冒险结构加关纪律的"每关一行集"细化到"每模板一行集";冒烟覆盖义务同批扩为遍历池内全部模板校验,不只抽中的那张。 - -### 抽签时机与可复现 - -**人话阶段**:什么时候抽、抽完怎么保证复盘对得上,是本系统接入现有随机纪律的两件事。抽签时点 = **开始关卡处理内、加载节点图之前**,逐关各抽一次(不是冒险开始一次抽齐三关)——抽签时机贴着"这一关的图要用"的时点,主种子的复现域天然覆盖。 - -``` -冒险结构(开始关卡:关卡序号、当前生命、生效上限) - → 关卡节点图生成:按关卡序号取模板池 → 抽一张(图模板抽签流,恰一 scope) - → 实例化为行集 → 交图合法性校验(关卡节点地图现行,零改动) - → 关卡节点地图加载行集 → 呈现选路停点(现行流程原样续跑) -``` - -可复现域沿用既有口径:主种子 + 全局取数计数器(2026-09-27 统一流;旧表述系并流前口径)(语义权威归[冒险结构](冒险结构.md)「失败重开与主种子」节,本文不复述)。抽签每次消费恰一个带编号的 scope,计数器随既有快照契约入档——[存档序列化](../表现与支撑/存档序列化.md)零新增域。同主种子同操作序列的两局,逐位同一张图。 - -教学位随骨架走:各骨架的"第一场战斗节点"沿用教学位纪律(首遇位固定数量不加骰)——教学位属性是骨架的内容标注,不跟节点编号走(拍板点①裁决后第一关也参与抽签,例外见下节)。 - -### 首次冒险的固定脚本(拍板点①裁决写入文档) - -**人话阶段**:教学关不该第一局就随机——玩家第一次玩,地图必须是设计好的那一张。拍板点①裁决(2026-09-27):**全部关卡都参与抽签,唯独玩家的第一次冒险全程走固定脚本**。这也是参照游戏的通用做法(首次冒险特殊脚本)。 - -| 事项 | 规则 | -|---|---| -| 判定标志 | 存档域新增布尔位「首次冒险已进行」(owner=存档序列化,实施批落 schema) | -| 判定时机 | 开始新冒险时读标志:false = 首次脚本模式;true = 正常抽签 | -| 脚本模式内容 | 全关零抽签——每关直接取池内的现行固定模板(即回滚档成员),逐位等价今日行为,无需新做脚本内容 | -| 置位时机 | 冒险收束点置位(完成/失败/放弃三结局同写)——存档级属性冒险期只读、写入只在收束挂点(既有纪律) | - -两条边界:首次冒险中途退出游戏(未到任何收束点)则标志未写,下次新冒险仍走脚本——教学重放,可接受;首次冒险内死亡或放弃即结算置位,第二次冒险起抽签。 - -测量口径:模拟试玩与数值验证夹具恒置标志为 true(永远走抽签路径)——首次脚本分支不进任何读数。 - -### 三级台阶路线 - -**人话阶段**:2026-09-21 呈报的三级台阶(图模板抽签 → 骨架固定+属性随机 → 全程序生成)随本批立项成文为正式路线。每一级都比上一级多一点随机,每一级都必须过同样两条不变量:①产物过图合法性校验(检查项口径归关卡节点地图,本文不复述);②商店房"每关恰 1、关底 Boss 前一位必经位"的编排约束在生成侧成立——冒烟断言照旧把关,校验零新增。 - -| 台阶 | 内容 | 前置条件 | -|---|---|---| -| 一:图模板抽签 | 每关模板池 N≥1,逐局从池中抽一张手工模板实例化 | 测量对账条款先行(见下节);每张新模板按内容纪律配齐数值行 | -| 二:骨架固定+属性随机 | 模板拓扑定型,节点类型在**候选槽位**(本文含义:模板给某个可变位列出的允许节点类型集合,实例化时从集合内均匀掷一个——例:某槽位允许{奖励,恢复},掷中哪个就是哪个)内掷定 | 台阶一完成;商店房所在位排除出候选槽位(保必经位) | -| 三:全程序生成 | 读参数(深度、分支密度、节点类型配比)直接构造图,构造失败重掷(重掷预算同棋盘生成 max_gen_attempts 纪律) | 台阶二完成;图合法性校验作最终守门 | - -台阶二的随机量入账:候选槽位掷定消费同一条图模板抽签流的后续 scope,计数器域照旧覆盖,可复现性零损失。台阶三的参数取值域届时随本文修订登记,本草案不预设。 - -台阶一用一句话说:**给每关手工做几张不同的地图骨架,每局开始时随机抽一张用**(用户裁决路线确认:骨架不完全固定、多份随机调取)。玩家看到的是同一关每局长得不一样——这局岔路多、下局一条窄道——但每张都是人工画好、审过合法性的图,不是程序乱长。台阶一不做两件事:房间类型不掷骰(某房间是奖励房还是恢复房仍由骨架定死——那是台阶二),程序不算图(那是台阶三)。首版池规模 = 每关 5 张(拍板点④),其中 1 张 = 现行固定图。 - -### 测量对账:别让随机污染读数 - -**人话阶段**:2026-09-21 呈报暂缓的三理由之一是"污染 MC 读数"——模拟试玩与数值验证的通关率是按固定图测的,图一随机,读数波动就混进了布局差异。本节是消解条款,三条: - -1. **分层出数**:模拟试玩与数值验证工具的读数按「关卡 × 图模板」分层记录;混合池的整体通关率 = 各模板条件通关率的加权平均(权重 = 抽中概率,均匀池即算术平均)。 -2. **基线可比**:基线批(与基线数据逐项比对、重投)跑固定模板口径——把池临时缩到 N=1(回滚档)或固定抽签 scope,保证新旧基线在同一张图上对话。 -3. **实施门**:随机量(扩池)上线排在[难度曲线与Boss](难度曲线与Boss.md)曲线调参批完成之后——现行行值 provisional 收带前叠加布局随机,归因会失真;抽签机制本身可先行落地(池保持 N=1 行为零变化,见拍板点③选项 C)。 - -另两条暂缓理由顺带消解:**类型集未稳**——五类节点封闭枚举已随商店房批定稿,扩类走文档修订的既有通道对模板同样适用(模板 schema 跟随枚举走);**内容量不足**——台阶一的模板就是内容批,按内容批节奏逐张走,不设批量生产目标。 - -## 拍板点(登记 [待办清单](../../../../待办清单.md),顺带更新条目) - -| # | 拍板点 | 状态 | -|---|---|---| -| ① | 第一关(教学关)是否参与抽签 | **已裁决(2026-09-27)**:参与——仅首次冒险走固定脚本,见「首次冒险的固定脚本」节 | -| ② | `node_map` 随机流增流 | **已裁决(2026-09-27 两轮复裁)**:统一用一个流——全游戏 rng 架构批先行(评估书已交付,2026-09-27),本特性实施排队其后 | -| ③ | 台阶一实施时点 | **已裁决(2026-09-27)**:机制先行骨架随后——特性内先落抽签机制(池暂 N=1 行为零变化)、骨架内容批随后扩池;整体仍排在架构批落地之后 | -| ④ | 首版池规模 | **已裁决(2026-09-27)**:每关 5 张起步(调参表已投值) | -| ⑤ | 抽签时点 = 关卡开始逐关抽 | **已裁决(2026-09-27)**:确认 | - -#### 证据面 A:随机流与「增流」是什么(拍板点②的背景) - -**人话**:本项目的随机数只有一个总入口(随机服务,代码名 rng_service),硬性红线禁止任何代码绕开它自己掷骰——"同一个种子+同样操作序列 = 逐位相同的一局"靠这条保证,调试复盘和模拟对账都依赖它。总入口内部按用途分账:每种用途占一栏,叫一条**流**(本文含义:随机服务内部按用途分开记账的一栏独立随机序列,各有各的编号,互不串账)。现行清单七条:雷图生成、奖励抽取、敌人数量掷骰、命中掷点、出招摇号、变异布置、GP 掉落——清单是封闭的,新用途必须在清单里开新栏。 - -图模板抽签是一笔新用途的随机账,要在清单里新开一栏(拟名 `node_map`)——「增流」就是这个动作:**给封闭流清单加一条新流**。它之所以要拍板:加流有固定成本(改代码 + 补一组校验用黄金向量 + 加冒烟断言,纪律规定的三件套),不是随手配置。 - -| 选项 | 内容 | 代价 | -|---|---|---| -| A 增流(原荐) | 清单加 `node_map` 栏,抽签独立记账 | 三件套成本;图的抽签可独立复现,与其它系统零耦合 | -| B 借现有流 | 从某条现有流取号 | 省三件套;但这笔账和那个系统的账搅在一起——重放对方系统的随机序列会被抽签挤位,复现口径变含糊,不推荐 | - -**裁决注记(2026-09-27)**:用户两轮复裁后终选「统一用一个流」(全面执行),执行路径 = 全游戏 rng 架构批先行、本特性排队其后。评估书已交付(2026-09-27,git 历史可查)——核心发现:字面目标「单一随机源、逐位可复现」现行架构已满足(七条流系同一主种子的七个盐值分栏而非七个随机源);待裁决项 = 是否进一步并掉分栏计数器(方案甲维持分栏 / 乙物理并流 / 丙并流+全事件日志)。 - -#### 证据面 B:台阶一详解与实施时点(拍板点③的背景) - -台阶一(图模板抽签)落地后的样子: - -- **玩家看到什么**:同一关,每局地图的房间连接方式不一样(这局岔路多、下局一条窄道),但每张都是人工画好、审过合法性的图——不是程序乱长。 -- **做三件事**:①每关 5 张骨架(拍板点④,其中 1 张 = 现行固定图);②开始关卡时抽一张实例化;③首次冒险走固定脚本(拍板点①)。 -- **不做两件事**:房间类型不掷骰(那是台阶二);程序不生成图(那是台阶三)。 -- **内容形态**:一个内容批 = 15 张骨架(3 关 × 5)+ 池内全模板加载校验 + 冒烟断言。骨架里只有房间和连线,**不新增敌人数值**——遭遇表按节点编号共用:两张骨架若都在 3 号位开战,3 号位打的敌人是同一套(表键不含骨架维);骨架差异体现在拓扑与房型排布,不体现在"同编号打不同敌人"。要打破这条需给遭遇表键加骨架维,归实施批 schema 拍板。 - -实施时点三个选项: - -| 选项 | 内容 | 后果 | -|---|---|---| -| A 机制+骨架立即全上 | 现在做完整内容批(含扩池到 5 张) | 曲线调参批未完成,数值基线在动;地图一随机,模拟读数的波动归因变难(数值动了还是图动了分不清) | -| B 全部等调参批完成(v0.1 原荐) | 机制与内容都排在曲线调参批后 | 读数对账最干净;机制落地要等 | -| C 机制先行、骨架随后(原荐) | 先落抽签机制但每关池暂放 1 张现行图(行为零变化),骨架内容批画好后一次扩到 5 张——扩池时点守测量对账实施门 | 机制与内容解耦:扩池前读数零污染,扩池后分层出数条款接管;不用等调参批 | - -## 依赖与输出 - -这张表就是删除任何一方时的影响面清单。 - -| 方向 | 系统 / 文档 | 接口要点 | -|---|---|---| -| 上游 | [冒险结构](冒险结构.md) | 开始关卡流程是抽签时点的宿主;主种子与派生流的语义权威;行集内容责任方(模板内容归它) | -| 上游 | [数据配置](../表现与支撑/数据配置.md) | 关卡表模板池列的承载与统一读取;node_map 统一流用途标签(扩签已落地 v0.5)与流种子派生公式的基础设施 | -| 上游 | [难度曲线与Boss](难度曲线与Boss.md) | 模板内遭遇数值的所有权;曲线调参批完成是台阶一的实施门 | -| 下游 | [关卡节点地图](关卡节点地图.md) | 实例化行集的供给方;其图合法性校验与全部行进规则零改动 | -| 下游 | [存档序列化](../表现与支撑/存档序列化.md) | 抽签 scope 计数器入既有快照契约(主种子 + 流计数器),零新增域;「首次冒险已进行」布尔位为唯一新增存档字段(实施批落 schema) | -| 下游 | [HUD框架](../表现与支撑/HUD框架.md) | 零新语义——节点态照旧读图,模板差异对呈现层透明 | - -## P0 最小闭环(台阶一实施批)——✅ 已落地(v0.5,2026-09-28) - -> 实施前置已解除:统一随机流批已落地(2026-09-27 两轮复裁——统一流+全事件日志);抽签接入形态 = 统一流扩签新用途标签 `node_map`(扩签通道 = 改代码 + 评审)。 - -1. 关卡表逐关行扩模板池结构(承载归数据配置,schema 细节随实施批定)。 -2. 池内全部模板加载期预校验(违规致命,fail-fast 不变)。 -3. 存档域加「首次冒险已进行」布尔位:开始新冒险读标志(false = 首次脚本模式,全关零抽签取现行固定模板),冒险收束点置位(三结局同写,写入只在收束挂点)。 -4. 开始关卡处理内抽签实例化(`node_map` 流恰一 scope——拍板点②)。 -5. 既有图合法性校验照跑零改动;关卡节点地图与战斗侧全链零改动。 -6. 冒烟断言:抽签确定性(同种子逐位同图)、池内全模板校验、N=1 池与现行固定图逐位等价、首次脚本分支(标志 false = 固定图 / true = 抽签)。 - -## P1 / P2 后置 - -| 优先级 | 内容 | 后置原因 | -|---|---|---| -| P1 | 台阶二:骨架固定+属性随机(候选槽位掷定) | 台阶一完成后另批立项;商店必经位的槽位排除规则顺带成文 | -| P2 | 台阶三:全程序生成(参数化构造) | 台阶二完成后另批立项;参数取值域与重掷预算顺带修订本文 | - -## 调参表 - -本系统无已锁数值。台阶一实施后进表: - -| 参数 | 域 | 现行值 | 说明 | -|---|---|---|---| -| 模板池大小 N | int [1,+∞),关卡表逐关行 | 每关 5(2026-09-27 拍板点④;2026-09-28 台阶一实施批落地,3 关 × 5) | N=1 = 回滚档;扩池 = 内容批 | -| 重掷预算(台阶三) | 未立项不设值 | — | 台阶三立项时随本文修订登记 | - -## 验收标准(草案——随拍板点裁决完成,实施批落地时按本节验收) - -- 池内全模板加载期通过图合法性校验,违规致命(校验面不只抽中的那张)。 -- 抽签确定性:同主种子同操作序列逐位同一张图;抽签 scope 可独立回放。 -- 回滚档成立:N=1 池的关卡与现行固定图逐位等价。 -- 首次冒险脚本:存档标志 false 时全程固定图(逐位等价现行行集),冒险收束点置位标志恰一次;标志 true 后每局抽签。 -- 商店房编排约束在每张模板上成立:每关恰 1 个商店房、关底 Boss 前一位必经位。 -- 零新面:关卡节点地图行进/兑付/收束断言与战斗侧寻址断言全绿,零改动。 -- 测量分层:模拟读数含「关卡 × 图模板」维度;基线批可固定模板复现。 -- 内容纪律:每张新模板的战斗与 Boss 节点在敌人与棋盘生成的数值表中有精确行(冒烟遍历池内全模板)。 - -## 待办 - -本系统无未决待办(结构随机生成池已落地);后续新增待办统一登记待办清单,本节不再逐条登记。 diff --git a/design/gdd/systems/冒险循环/关卡节点地图.md b/design/gdd/systems/冒险循环/关卡节点地图.md index 13508256..17c0136a 100644 --- a/design/gdd/systems/冒险循环/关卡节点地图.md +++ b/design/gdd/systems/冒险循环/关卡节点地图.md @@ -61,7 +61,7 @@ 商店房的编排规则(2026-09-20 用户拍板):每关**恰 1 个**商店房,位置 = **关底 Boss 前一位**——哈迪斯式的"决战前最后一个补给点":买到的属性还有整段战斗可消费,错过的成长也没有第二家店可补。Boss 前一位同时是**必经位**:图拓扑收束使所有入口→Boss 的路径都穿过它,成长保底成为图结构事实而非玩家自觉。这条位置约束不由加载校验承载——图合法性六检零新增,商店房的"每关恰 1 + 必经"由冒烟断言把关。 -每个节点在关卡内领一个**节点编号**(本文含义:关卡内不重复的序号,用来当战斗的定位地址;数据键沿用切片字段 `node_depth`)。Boss 的编号恒为全图最大——"最深处的房间是关底"这条直感由此保留。单链特例:一张每步只有一条连线的图就是一条链,此时节点编号等于它前面走过的战斗场数。第一关行集就是单链特例,切片代码零改动运行;分支图行集已落地(v1.0.1 起;模板池见[关卡节点图生成](关卡节点图生成.md))。 +每个节点在关卡内领一个**节点编号**(本文含义:关卡内不重复的序号,用来当战斗的定位地址;数据键沿用切片字段 `node_depth`)。Boss 的编号恒为全图最大——"最深处的房间是关底"这条直感由此保留。单链特例:一张每步只有一条连线的图就是一条链,此时节点编号等于它前面走过的战斗场数。第一关行集就是单链特例,切片代码零改动运行;分支图行集已落地(v1.0.1 起;图的来源与模板池随关卡节点图重构批重写,旧生成文档已删)。 呈现侧口径(2026-09-17 用户拍板):节点图的画面表达走**方块地牢观感**——节点画成地牢房间的方块、连线画成通道——但逻辑拓扑就是本文的节点图,不产生任何额外选路或探索语义。关卡画面本体即节点链进度的呈现载体(选路覆盖层的常驻形态,节点态直接读图:已过暗金 / 当前金 / 候选下一跳通道亮金 / Boss 封印黑描边(旗朱→封印紫→封印黑 #000000,2026-09-28 用户拍板现行)),不另设进度条组件;视觉规格归 [HUD 框架](../表现与支撑/HUD框架.md)。 diff --git a/design/gdd/systems/冒险循环/冒险结构.md b/design/gdd/systems/冒险循环/冒险结构.md index 2cd50169..c024aad8 100644 --- a/design/gdd/systems/冒险循环/冒险结构.md +++ b/design/gdd/systems/冒险循环/冒险结构.md @@ -261,7 +261,7 @@ GP(显示名「GP」)是冒险内的一次性属性提升货币:战斗胜 | 参数 | 域 | 现行值 | 说明 | |---|---|---|---| -| 关卡行集(关数与节点链模板) | 关卡表逐关行 | 三关现行(逐关 templates 池 3 关 × 5,模板 0 = 回滚档——见[关卡节点图生成](关卡节点图生成.md)) | 加关 = 内容批(链行 + 敌我数值 + 新元素同批);L1 回滚档模板 = 两战 → 奖励 → 两战 → 恢复 → 关底 Boss(7 节点,战斗深度 5) | +| 关卡行集(关数与节点链模板) | 关卡表逐关行 | 三关现行(逐关 templates 池 3 关 × 5,模板 0 = 回滚档;生成机制随关卡节点图重构批重写,旧生成文档已删) | 加关 = 内容批(链行 + 敌我数值 + 新元素同批);L1 回滚档模板 = 两战 → 奖励 → 两战 → 恢复 → 关底 Boss(7 节点,战斗深度 5) | | 恢复比例 | int [0,100],逐关行 | 见 level.tres rest_heal_pct(provisional) | 恢复点回复生效上限的百分比;随上限加成同步放大;100 = 恢复点变全满泉,0 = 死节点 | | 上限提升 | int [0,999],冒险表逐件列 | adventure_table bonus_attack_flat / bonus_max_hp_flat / bonus_armor_flat(provisional) | 三选一属性件各自兑付值;值锚与上调约束归难度曲线与Boss | | 三选一件值(其余) | int [0,999],冒险表 kind×tier 列族 | adventure_table curio_value_*(GP 袋 / AP 件 / 恢复 / 刷新,provisional) | 令牌件值读表;道具件授予件数随秘宝件出池退役 | diff --git a/design/gdd/ux/level-map.md b/design/gdd/ux/level-map.md index 3f62caec..902bc4c3 100644 --- a/design/gdd/ux/level-map.md +++ b/design/gdd/ux/level-map.md @@ -7,7 +7,7 @@ > **Template**: UX Spec > **覆盖范围**: 独立屏形态(关卡停点全景)· 入口停点 · 岔路停点 · 单链停点 · 放弃冒险入口 > **不覆盖**: 节点覆盖层(NodeOverlay——奖励/恢复兑付反馈,spec:[node-reward.md](node-reward.md))、商店覆盖层(spec:[shop.md](shop.md))、关卡结算屏([level-clear.md](level-clear.md))、战斗屏([battle.md](battle.md)) -> **机制权威**: [关卡节点地图](../systems/冒险循环/关卡节点地图.md)(选路、兑付、停点语义;节点图逐局随机的来源另见[关卡节点图生成](../systems/冒险循环/关卡节点图生成.md)——只换图的来源,不换本屏的呈现语义);**系统契约**: [HUD框架](../systems/表现与支撑/HUD框架.md)(订阅纪律、模态层级、可访问性基线) +> **机制权威**: [关卡节点地图](../systems/冒险循环/关卡节点地图.md)(选路、兑付、停点语义;节点图的来源随关卡节点图重构批重写,旧生成文档已删——只换图的来源,不换本屏的呈现语义);**系统契约**: [HUD框架](../systems/表现与支撑/HUD框架.md)(订阅纪律、模态层级、可访问性基线) --- diff --git a/design/research/Alpha未完成事项梳理-2026-10-13.md b/design/research/Alpha未完成事项梳理-2026-10-13.md index a8d067c3..cfa5253d 100644 --- a/design/research/Alpha未完成事项梳理-2026-10-13.md +++ b/design/research/Alpha未完成事项梳理-2026-10-13.md @@ -63,7 +63,7 @@ | 编号 | 事项 | 状态 | 来源 | |---|---|---|---| | D1 | 剧情 / 世界观文本资产 | **缺失且有意不做**——[05-不做清单](../gdd/05-不做清单.md)「重叙事」永久排除(不写长篇文本,世界观只做碎片点缀)。现行只有层名(地精洞窟 / 幽暗地域 / 灰矮人矿城)与显示名,**零描述文本、零碎片叙事载体** | 05 确定不做节;[00-游戏概念](../gdd/00-游戏概念.md) | -| D2 | 关卡节点图模板池扩容(现行 15 骨架 = 3 关 × 5,随 A1 重构需重生成) | **待做**(A1 连带面) | [关卡节点图生成](../gdd/systems/冒险循环/关卡节点图生成.md);06 A1 条「范围」段 | +| D2 | 关卡节点图模板池扩容(现行 15 骨架 = 3 关 × 5,随 A1 重构需重生成) | **待做**(A1 连带面) | 关卡节点图生成(旧版文档已删、随重构重写);06 A1 条「范围」段 | | D3 | 事件类节点候选 | **缺失**(无内容系统承载,扩类须走文档修订) | [关卡节点地图](../gdd/systems/冒险循环/关卡节点地图.md) P2 | #### 乙-3 角色与敌人配置 diff --git a/待办清单.md b/待办清单.md index a22bd434..8f45c5ea 100644 --- a/待办清单.md +++ b/待办清单.md @@ -95,7 +95,7 @@ **现行实态**(`level.tres` 实查,三关各 5 张模板):**第一关五张模板全是单链排列变体**——7 个节点=战斗 ×4 + 奖励 + 休整 + Boss,战斗深度序单调保难度坡,**变化面只有奖励与休整两位的先后次序**,全链零分叉,玩家在选路上**没有任何选择**;第二/三关是网状图(10 节点,带 `next` 分支,最大层宽 4–5),有分叉,但用户仍判选择量不足。参考方向=Peglin(哥布林弹珠)的节点图移动与选路方式。 -**范围(重构面,非呈现面)**:节点数量、分叉度、选路自由度。连带三面——① [关卡节点图生成](design/gdd/systems/冒险循环/关卡节点图生成.md)(模板池与抽签机制,现行 15 张骨架=3 关 ×5 需重生成);② [level-map](design/gdd/ux/level-map.md)(选路枢纽三停点布局定稿版,图结构改则屏面随之改);③ [敌人系统](design/gdd/systems/战斗循环/敌人系统.md)(遭遇表按 `enemy.tres` 的 (level_index, node_depth) 坐标索引,节点数与编号一改,行集坐标与首遇教学位断言面全部随动)。 +**范围(重构面,非呈现面)**:节点数量、分叉度、选路自由度。连带三面——① 关卡节点图生成(旧版文档已删、随重构重写;现行 15 张骨架=3 关 ×5 已判过期,随重构清理);② [level-map](design/gdd/ux/level-map.md)(选路枢纽三停点布局定稿版,图结构改则屏面随之改);③ [敌人系统](design/gdd/systems/战斗循环/敌人系统.md)(遭遇表按 `enemy.tres` 的 (level_index, node_depth) 坐标索引,节点数与编号一改,行集坐标与首遇教学位断言面全部随动)。 **量化要求补登(2026-10-16 playnote 用户补写)**:「需要统计一下第 123 关 path 的路径长度,路径长度需要递增,并且后续关卡的节点数增幅应该更大」(第 123 关=第 1/2/3 关)——重构设计讨论的验收方向两条:先实测三关路径长度基线,再定递增曲线与后续关增幅尺度。 @@ -103,7 +103,7 @@ **缺口**:还差参考调研+重构方案的设计讨论(含路径长度基线实测与递增曲线两条验收方向),过人闸后才能开卡。 -**归属**:[关卡节点地图](design/gdd/systems/冒险循环/关卡节点地图.md)(图结构与节点语义,主责)+ [关卡节点图生成](design/gdd/systems/冒险循环/关卡节点图生成.md)(模板池与抽签)+ [level-map](design/gdd/ux/level-map.md)(选路呈现)+ [敌人系统](design/gdd/systems/战斗循环/敌人系统.md)(遭遇行集坐标连带);版本标准侧已登记为 Alpha 待做项,见 [08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「一 · 系统 · 冒险循环」 +**归属**:[关卡节点地图](design/gdd/systems/冒险循环/关卡节点地图.md)(图结构与节点语义,主责)+ 关卡节点图生成(旧版文档已删、随重构重写)+ [level-map](design/gdd/ux/level-map.md)(选路呈现)+ [敌人系统](design/gdd/systems/战斗循环/敌人系统.md)(遭遇行集坐标连带);版本标准侧已登记为 Alpha 待做项,见 [08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「一 · 系统 · 冒险循环」 **状态**:待文档设计 From 33e1f1105783589cb86f14d66e25affa0f220155 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 02:45:57 +0800 Subject: [PATCH 45/59] =?UTF-8?q?test(=E5=8D=A1=E2=91=A1=20T7=E8=A1=A5?= =?UTF-8?q?=E6=BC=8F):=20=E8=A1=A5=E9=BD=90=20=C2=A79=20=E6=AD=A3=E5=90=91?= =?UTF-8?q?=E9=AA=8C=E6=94=B6=E4=B8=BB=E5=8A=9B=20V1/V2/V6=20=E4=B8=8E?= =?UTF-8?q?=E5=85=A8=20Vn=20=E6=A0=87=E6=B3=A8=20+=20V1/V4=20=E5=8F=98?= =?UTF-8?q?=E5=BC=82=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 前批合回时漏建卡② §9 逐需求点「正向验收主力」断言(四桶机制),仅靠迁移旧测+V12 兜底—— V12 formed/rules 输出面不作判据,adventure 桶跨战持久若坏不会红,核心缺陷消解无回归网。本批补: - V1 冒烟新段:同一 RunLedger 两 begin_battle 各真实 request_dig,断 adv_twin_digs 经 ctx 就地写宿主字典跨战累积=2 - V2:start_adventure 后 adventure 桶置空(feat_vouchers) - V6 冒烟新段:次战新编排器 fx_counters_battle 天然空、battle 桶 insurance_used 读 0 - V3/V4/V5/V7/V8/V9/V10 补〔无状态化 Vn〕尾缀使 §9 可追溯 - 变异验证:V1 断 adventure 桶引用改新建空字典→3 条红;V4 断 level 桶不共享→红(证回归网真拦得住) --- game/smoke/smoke_all.gd | 56 ++++++++++++++++++- game/tests/static_scan.sh | 2 +- game/tests/unit/core/effect_words_t1_test.gd | 2 +- game/tests/unit/core/feat_vouchers_test.gd | 7 ++- .../data_config/counter_prefix_fatal_test.gd | 2 +- 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/game/smoke/smoke_all.gd b/game/smoke/smoke_all.gd index dd8c2b10..7f8cf2e8 100644 --- a/game/smoke/smoke_all.gd +++ b/game/smoke/smoke_all.gd @@ -697,6 +697,7 @@ func _run_core_smoke(db, rng) -> void: _smoke_meta() _smoke_tree() _smoke_tree_rules() + _smoke_counter_buckets() _smoke_node_map_templates() @@ -6049,6 +6050,57 @@ func _smoke_tree() -> void: # ---- 天赋树六键行为冒烟(V10:开局姿态窗/危险直觉限次/财富之道聚散/守侧失误补偿; # 引擎直构 + 编排授予段直注(_grant_seg._judge_seal=结算授予段封印判定单口))---- +func _smoke_counter_buckets() -> void: + print("--- 效果引擎无状态化四桶正向验收(卡② §9 V1/V6)---") + # V1——adventure 桶跨战持久:同一 RunLedger 下两战各真实 request_dig 一次, + # 断付费计数经 ctx 就地写入宿主字典并跨战累积(副本搬运态:读不到上一战值→第 2 战仍 1,此断言会红)。 + var led = load("res://core/run_ledger.gd").new() + var RigS = load("res://core/battle_orchestrator.gd") + var RngS = load("res://core/rng_service.gd") + var enc1 = {"level_index": 1, "node_depth": 0, "hero_hp": 40, "hero_atk": 8, "hero_max_hp": 40, + "hero_armor_class": 10, "hero_ap_bonus": 0, "attunement": [], "attune_charges": {}, + "feats": ["twin_pick"], "tree_rules": [], "battle_index": 1, + "bonus_ref": {"atk": 0, "max_hp": 0, "armor_class": 0}, "voucher_rap": 0, "voucher_time_sand": 0, + "node_type": "battle", "ledger": led} + var o1 = RigS.new(_db, _fresh_rng(779301)) + o1.begin_battle(enc1) + var dig1: bool = o1.action_economy.request_dig(0, false) + check(dig1, "V1 第1战真实 request_dig 受理(begin_battle 后 ACTIVE 相位)〔无状态化 V1〕") + check(int(led.adventure_counters.get("adv_twin_digs", 0)) == 1, + "V1 第1战付费挖格经 ctx 就地写 adventure 桶=1(无 export 搬运时点)〔无状态化 V1〕") + var enc2 = enc1.duplicate(true) + enc2["battle_index"] = 2 + var o2 = RigS.new(_db, _fresh_rng(779302)) + o2.begin_battle(enc2) + check(EffectEngine.counter(o2.counters_ctx, "adv_twin_digs") == 1, + "V1 第2战 begin_battle 经 ctx 读到上一战持久值=1(读路径走宿主字典引用,非副本种子回灌)〔无状态化 V1〕") + o2.action_economy.request_dig(0, false) + check(int(led.adventure_counters.get("adv_twin_digs", 0)) == 2, + "V1 第2战挖后 adventure 桶跨战累积=2(run_ledger:42 判空早退缺陷消解的回归钉面——旧副本态恒 1)〔无状态化 V1〕") + # V6——battle 桶随宿主销毁:第1战标错落 insurance_used(battle 桶无前缀),次战新编排器读 0。 + var encA = {"level_index": 1, "node_depth": 0, "hero_hp": 40, "hero_atk": 8, "hero_max_hp": 40, + "hero_armor_class": 10, "hero_ap_bonus": 0, "attunement": [], "attune_charges": {}, + "feats": ["perfect_insurance"], "tree_rules": [], "battle_index": 1, + "bonus_ref": {"atk": 0, "max_hp": 0, "armor_class": 0}, "voucher_rap": 0, "voucher_time_sand": 0, + "node_type": "battle", "ledger": load("res://core/run_ledger.gd").new()} + var oA = RigS.new(_db, _fresh_rng(779401)) + oA.begin_battle(encA) + var safe_a: Variant = null + for ca in oA.minesweeper.current_board().all_cells(): + if not oA.minesweeper.current_board().is_mine(ca): + safe_a = ca + break + oA._grant_seg._judge_seal({"cell": safe_a, "hit": false}, 1) + check(EffectEngine.counter(oA.counters_ctx, "insurance_used") == 1, + "V6 第1战标错落 battle 桶 insurance_used=1(_apply_counter_hit 静态写口经 ctx)〔无状态化 V6〕") + var encB = encA.duplicate(true) + encB["battle_index"] = 2 + var oB = RigS.new(_db, _fresh_rng(779402)) + oB.begin_battle(encB) + check(EffectEngine.counter(oB.counters_ctx, "insurance_used") == 0, + "V6 battle 桶随宿主销毁:次战新编排器 fx_counters_battle 天然空,读 insurance_used=0〔无状态化 V6〕") + + func _smoke_tree_rules() -> void: print("--- 天赋树六键行为(V10:窗/限次/聚散/守侧)---") # 开局姿态组:每关首轮窗(battle_index 事实——引擎直构 + 自建 ctx) @@ -6078,13 +6130,13 @@ func _smoke_tree_rules() -> void: got_add = true check(got_mult and got_add, "锋:踩雷减半命中+限次记账(counter 0<2 闸开——damage_mult+counter_add 双行同预评估态)") EffectEngine.counter_add(ctx_fz, "lvl_tree_sense_sharp_used", 2) # 直调置数(V10 注入口径——置 level 桶计数后走事件路径) - check((fz.dispatch(ctx_fz, "mine_hit", {}, Callable()) as Array).is_empty(), "锋:限次耗尽全额(counter 2 不<2 闸关——每关限次 provisional 2)") + check((fz.dispatch(ctx_fz, "mine_hit", {}, Callable()) as Array).is_empty(), "锋:限次耗尽全额(counter 2 不<2 闸关——每关限次 provisional 2)〔无状态化 V5〕") var fz2 = load("res://core/effect_engine.gd").new(null) fz2.rebuild([], [], ["sense_sharp"]) var ctx_fz2 := EffectContext.new() ctx_fz2.level_bucket = lvl_shared # 挂同一 level 桶引用(新形态跨战持久:无 export/seed,同字典即持久) check((fz2.dispatch(ctx_fz2, "mine_hit", {}, Callable()) as Array).is_empty(), - "锋:限次跨战持久(level 桶共享引用——替代旧副本搬运链)") + "锋:限次跨战持久(level 桶共享引用——替代旧副本搬运链)〔无状态化 V4〕") # 守侧五场景(契约 12):编排 rig——begin_battle 携 sense_guard,授予段 _grant_seg._judge_seal 直注 var orch = load("res://core/battle_orchestrator.gd").new(_db, _fresh_rng(777001)) check(orch.begin_battle({"level_index": 1, "node_depth": 0, "hero_hp": 40, "hero_atk": 8, "hero_max_hp": 40, diff --git a/game/tests/static_scan.sh b/game/tests/static_scan.sh index bdabdc7b..42bbdb91 100644 --- a/game/tests/static_scan.sh +++ b/game/tests/static_scan.sh @@ -228,7 +228,7 @@ else echo "$S12_FACE" | tr '\n' '\0' | xargs -0 grep -En "$S12_SYM" 2>/dev/null fail=1 else - echo "[static_scan] S12 ok(扫描面 $S12_FC 个 .gd/.tres,旧件零残留)" + echo "[static_scan] S12 ok(扫描面 $S12_FC 个 .gd/.tres,旧件零残留)〔无状态化 V10〕" fi fi fi diff --git a/game/tests/unit/core/effect_words_t1_test.gd b/game/tests/unit/core/effect_words_t1_test.gd index d0c44dc2..0979ef5d 100644 --- a/game/tests/unit/core/effect_words_t1_test.gd +++ b/game/tests/unit/core/effect_words_t1_test.gd @@ -113,7 +113,7 @@ func _init() -> void: "V4:counter_spend 静态写口消耗(用后清零语义承载面)〔专长批 V4〕") fx5.dispatch(ctx5, "round_start", {"round": 2}) Kit.check_quiet(EffectEngine.counter(ctx5, "round_mines") == 0, - "V4:round_ 前缀计数器随 round_start 整桶清空(旧 reset_at 名单声明制换代为前缀归桶)〔专长批 V4〕") + "V4:round_ 前缀计数器随 round_start 整桶清空(旧 reset_at 名单声明制换代为前缀归桶)〔无状态化 V8〕") # battle 桶对照:无前缀 helm_layers 不受 round_start 影响(跨 round_start 存活) var fx6 = EffectEngineScript.new(null) var ctx6 := EffectContext.new() diff --git a/game/tests/unit/core/feat_vouchers_test.gd b/game/tests/unit/core/feat_vouchers_test.gd index 2bece985..0179721c 100644 --- a/game/tests/unit/core/feat_vouchers_test.gd +++ b/game/tests/unit/core/feat_vouchers_test.gd @@ -26,6 +26,9 @@ func _init() -> void: Kit.check_quiet(false, "V9 前置:冒险启动") quit(Kit.finish("feat_vouchers")) return + # V2——adventure 桶新冒险置空:start_adventure 后宿主字典为空(寿命随 RunLedger,无残留) + Kit.check_quiet(a.run_ledger.adventure_counters.is_empty(), + "V2:新冒险 adventure 桶置空(start_adventure 后 run_ledger.adventure_counters 为空)〔无状态化 V2〕") # V9-1 刷新券:入存量账(冒险级)——反例=写进 _attune_refresh_x(X 每停点重置会吞存量) a._reset_refresh_x() # X 归零基线(模拟新停点) @@ -136,7 +139,7 @@ func _init() -> void: Kit.check_quiet(b4.resume_adventure(bp_legacy2, {}), "V13:旧档 adventure_counters 含改名前旧键续玩受理零崩溃(无迁移——旧键留桶成死键)〔卡② V13/H1〕") Kit.check_quiet(int(b2.run_ledger.adventure_counters.get("pain_layers", -1)) == 3 and b2.refresh_stock() == 2, - "V16:续玩回填逐项一致(计数恢复——跨战账不丢)〔专长批 V16〕") + "V16:续玩回填逐项一致(adventure 桶随断点往返·计数恢复)〔无状态化 V3〕") # V25 完美保险专长验收组(R2 全项:装载/限次一次/计数纯净/两账相减/跨战清零/事件不吞) var fi: Dictionary = db.feats.row_by_id("perfect_insurance") Kit.check_quiet(not fi.is_empty() and String(fi.get("rarity", "")) == "rare" @@ -178,7 +181,7 @@ func _init() -> void: orch._perfect_hit_false = 1 orch._perfect_hit_true = 1 Kit.check_quiet(orch.perfect_sweep_earned(), - "判定相减:误标 1 − 豁免 1 = 有效 0 且标中≥1 → 完美成立〔卡② R2 真值表〕") + "判定相减:误标1−豁免1=有效0且标中≥1→完美成立(保险每战限次一次迁移保绿)〔无状态化 V7〕") orch._perfect_hit_true = 0 Kit.check_quiet(not orch.perfect_sweep_earned(), "判定守卫:标中数 0 时零误标也不成立(整图 ≥1 标中条件零松动)〔卡② R2 真值表〕") diff --git a/game/tests/unit/data_config/counter_prefix_fatal_test.gd b/game/tests/unit/data_config/counter_prefix_fatal_test.gd index f5289ec2..6f0e1951 100644 --- a/game/tests/unit/data_config/counter_prefix_fatal_test.gd +++ b/game/tests/unit/data_config/counter_prefix_fatal_test.gd @@ -67,5 +67,5 @@ func _init() -> void: if not _assert_rejected(BAD_REF_DIR, PROBE_REF, "counter_prefix_fatal_test/②悬空读点"): quit(2) return - print("[counter_prefix_fatal_test] 双断言均正确拒绝(前缀合法性 + 引用闭合)") + print("[counter_prefix_fatal_test] 双断言均正确拒绝(前缀合法性 + 引用闭合)〔无状态化 V9〕") quit(1) From d8622ee271d3a3a4038afbec73ecaf633a130c2c Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 02:47:10 +0800 Subject: [PATCH 46/59] =?UTF-8?q?docs(=E5=8D=A1=E2=91=A1=E6=8A=A5=E5=91=8A?= =?UTF-8?q?=E6=9B=B4=E6=96=B0):=20=C2=A79=20=E9=80=90=E9=9C=80=E6=B1=82?= =?UTF-8?q?=E7=82=B9=20V1-V14=20=E5=85=A8=E8=90=BD=E5=9C=B0=E8=A1=A8=20+?= =?UTF-8?q?=20=E8=A1=A5=E6=BC=8F=E8=AE=B0=E5=BD=95=20+=20V1/V4/V9/V10=20?= =?UTF-8?q?=E5=8F=98=E5=BC=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- reports/iter32-卡②实现报告-2026-10-20.md | 26 ++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/reports/iter32-卡②实现报告-2026-10-20.md b/reports/iter32-卡②实现报告-2026-10-20.md index d8cac9e5..a505a923 100644 --- a/reports/iter32-卡②实现报告-2026-10-20.md +++ b/reports/iter32-卡②实现报告-2026-10-20.md @@ -39,8 +39,30 @@ | T4 round 泛化+宿主清零确认 | 并入 T2/T3 | ✅(round 整桶 clear+宿主 new 天然空) | | T5 前缀双落点+引用闭合+负面套件+manifest | d402ea14, 4c5bdbc9 | ✅ | | T6 数据行/合成行改名+domain/reset_at 删 | 7f45f904 | ✅ | -| T7 断言迁移+S12+V12+变异 | b226a292, 003581f4, a9d5ac13, b42463c9 | ✅(见下) | -| T8 产出物 | 本批 reports | 进行中 | +| T7 断言迁移+§9 正向断言+S12+V12+变异 | b226a292, 003581f4, a9d5ac13, b42463c9, 33e1f110 | ✅(§9 见下) | +| T8 产出物 | 本批 reports | ✅ | + +## §9 逐需求点正向验收主力(V1–V14·补漏记录 33e1f110) + +> 首合(d00f24a8)时本节缺 V1/V2/V6——只靠迁移旧测+V12 兜底。V12 formed/rules 输出面不作判据,adventure 桶跨战持久若坏不会红,核心缺陷消解无回归网。补漏批建齐并打〔无状态化 Vn〕尾缀: + +| V | 需求点 | 落点 | 断言 | 变异拦截 | +|---|---|---|---|---| +| V1 | adventure 桶跨战持久(真实事件面) | smoke `_smoke_counter_buckets` | 同一 RunLedger 两 begin_battle 各真实 request_dig→adv_twin_digs 经 ctx 累积=2、第2战读到持久值1 | **变异红**(桶引用改新建空字典→3 断言 FAIL) | +| V2 | adventure 桶新冒险置空 | feat_vouchers | start_adventure 后 run_ledger.adventure_counters 空 | — | +| V3 | adventure 桶随断点往返 | feat_vouchers V16 换代 | 写桶→快照→回读逐键一致 | — | +| V4 | level 桶同关跨战保持 | smoke `_smoke_tree_rules` | 共享 level 字典引用第2战读到限次值 | **变异红**(level 不共享→FAIL) | +| V5 | tree_sense 每关限 2 | smoke `_smoke_tree_rules` | 置 2 后 mine_hit 闸关零命中 | — | +| V6 | battle 桶随宿主销毁 | smoke `_smoke_counter_buckets` | 次战新编排器读 insurance_used=0 | — | +| V7 | 保险每战限次迁移保绿 | feat_vouchers V25 | 组内断言原样绿(双账不改面) | — | +| V8 | round 桶轮始清空 | effect_words_t1 ⑦ | round_ 前缀随 round_start 整桶 clear | — | +| V9 | 前缀致命+引用闭合 | counter_prefix_fatal_test | meta_/悬空读点两断言拒绝 | **变异红**(前缀分支置 false/闭合降 info→quit2) | +| V10 | 旧件零残留 | static_scan.sh S12 | game/**/*.gd+*.tres 旧符号 0 命中 | **变异红**(注入 counters_export→命中) | +| V11 | 旧断言同批摘除 | F2 迁移 | smoke 裸引擎段+4 单测件 ctx 化 | — | +| V12 | 同种子复放三组 | parity_compare.py | off 逐位/formed·rules 输入面恒等 | rules≠off 0 相同=非空转 | +| V13 | 旧档加载不崩 | feat_vouchers | 含改名前旧键 resume 受理零崩 | — | +| V14 | tree_sense 削弱目检 | 实机目检清单 | 每关第3次无减半/无返 AP | 用户实战验(只登记) | + ## V12 同种子复放三组判读(完成定义 6 主力证据) From feaf01454a0ab86c25e61e72d1b169e81cae0ad4 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 03:42:37 +0800 Subject: [PATCH 47/59] =?UTF-8?q?docs(=E9=AA=8C=E6=94=B6=E9=97=AD=E5=90=88?= =?UTF-8?q?):=20=E6=B5=8B=E8=AF=95=E8=A7=84=E8=8C=83=E6=96=B0=E5=A2=9E=20?= =?UTF-8?q?=C2=A79=20=E6=94=B9=E5=8A=A8=E7=BA=A7=E9=AA=8C=E6=94=B6?= =?UTF-8?q?=E9=97=AD=E5=90=88=E2=80=94=E2=80=94=E6=AF=8F=E4=B8=AA=E9=9C=80?= =?UTF-8?q?=E6=B1=82=E7=82=B9=E4=B8=8E=E8=A1=8C=E4=B8=BA=E6=94=B9=E5=8A=A8?= =?UTF-8?q?=E9=83=BD=E8=A6=81=E7=9C=9F=E5=AE=9E=E5=85=A5=E5=8F=A3=E6=96=AD?= =?UTF-8?q?=E8=A8=80=EF=BC=8B=E6=92=A4=E9=94=80=E8=AF=81=E6=98=8E=EF=BC=8C?= =?UTF-8?q?=E5=90=88=E5=9B=9E=E5=89=8D=E7=8B=AC=E7=AB=8B=E9=AA=8C=E6=94=B6?= =?UTF-8?q?=E5=AE=A1=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 病根=测试规范 §5.2 只要求「每条清单条目至少一个自动断言」,没要求断言从改动的真实入口进入: 裸 EffectEngine 断言可替 BattleOrchestrator 接线,报告写「V1 绿」而 V1 断言并不存在。 - test-conventions §9(9.1–9.8):验收单位=行为改动;四层与真实入口;改动—验收对照表六列 双端对上(需求点正向、diff 反向、断言挂载测试侧);撤销证明(改既有行为回退变红、新增行为 变异变红);禁削弱测试;明确不要求 TDD;合回前独立验收审计;旧卡不回头改、开工前补齐 - process-conventions §3:第 7 条挂对照表、第 9 条补撤销证明、第 10 条合回前审计、新增第 16 条 - AGENTS.md 硬性红线新增「验收闭合」,与变异验证并列 - pipeline_gate 新增 C3:卡片须有对照表节、五个必需列、至少一行、必填格非空、全文声明验收审计; 只查结构不判语义(生效 2026-10-21,按卡片文件名日期追新) - reports/README 与 batch-closure 同步验收审计报告的落点与退役判据 - 待办清单登记「验收闭合规则——下一次迭代实测评估」,按规则评估红线等真实迭代检验 --- AGENTS.md | 1 + design/engineering/process-conventions.md | 7 +- design/engineering/test-conventions.md | 63 ++++++++++++++- reports/README.md | 3 +- tools/pipeline_gate.py | 93 ++++++++++++++++++++++- 待办清单.md | 8 ++ 6 files changed, 167 insertions(+), 8 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index b695f3a9..2735d352 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -61,6 +61,7 @@ - MC/模拟:无数值改动零跑;档位硬闸见 `sim-data/README.md`「MC 采集档位表」,一档只能由用户发起 - 闸机轮次纪律:新码先孤立验证 → 出红只跑红件最小单元 → 长批先最小参数试车 → 开工扫坑册(process-conventions §6) - 变异验证——新增/改写验收函数必须变异变红才算验收成立;无变异红记录只写「已实现,拦截能力未证」(test-conventions §6) +- **验收闭合**——每个需求点与每个行为改动都要有从真实入口进入的验收断言,撤销该改动能让对应断言变红;禁删断言/放宽阈值换绿;合回前独立验收审计未过不得合并(细则=test-conventions §9+iter 技能第 5 步) - 规则评估——没在真实任务上评估过的规则修订,不算完成。 - 中间产物吸收即死——结论先吸收进权威文档、未决先迁待办清单,文件即删且永不提交(doc-conventions 第 11 节) - **禁写变更记录**——文档与代码文件内一律禁设「版本历史/修订记录/变更记录/修改记录/更新记录/更新日志」节或表格,禁写「本版改了哪些条款」式逐版本叙述与 `# 2026-xx-xx 缺陷修批——` 式行内修订注记;沿革只进 git commit log。版本号可作文档现行身份标记留在文首状态行与正文引用中(doc-conventions 第 5 节,机检闸 gdd_lint R4 反转拦截) diff --git a/design/engineering/process-conventions.md b/design/engineering/process-conventions.md index 64fa77f9..76ef1010 100644 --- a/design/engineering/process-conventions.md +++ b/design/engineering/process-conventions.md @@ -45,17 +45,18 @@ 6. **涉数值改动先采改前读数**——与改后同随机种子配对比较并写明逐项比对口径;无数值改动禁跑模拟 **实施** -7. **新功能必配新测试**——新增玩法/机制必须配套新测试套件进 `tests/run_all`;没有对应测试的变更不许合并 +7. **新功能必配新测试**——新增玩法/机制必须配套新测试套件进 `tests/run_all`;没有对应测试的变更不许合并;并按 test-conventions §9 挂进改动—验收对照表,没有对照表行的行为改动同样不许合并 8. **验收改动先行声明**——验收变化(基线换代/探针增改/旧断言改判)预先写进需求卡片,禁事后补 -9. **验收函数变异验证**——新增/改写的验收函数(冒烟断言/探针自检/闸机判据)必须配一次变异验证:故意把被测件改坏成该类缺陷形态 → 跑最窄那道闸确认变红 → `git checkout` 精确还原;变异点/跑的闸/红输出摘要/还原结论四件记入实现报告变异验证记录表;**无变异红记录的断言不写「已验收」,只写「已实现,拦截能力未证」**(细则见 test-conventions §6) +9. **验收函数变异验证**——新增/改写的验收函数(冒烟断言/探针自检/闸机判据)必须配一次变异验证:故意把被测件改坏成该类缺陷形态 → 跑最窄那道闸确认变红 → `git checkout` 精确还原;变异点/跑的闸/红输出摘要/还原结论四件记入实现报告变异验证记录表;**无变异红记录的断言不写「已验收」,只写「已实现,拦截能力未证」**(细则见 test-conventions §6);行为改动另做撤销证明(test-conventions §9.4),两类证明都记入实现报告 **完成** -10. **批末按域验收才合并**——在任务 worktree 内跑 `tools/run_all_gates.sh`,**按本批改动域选档**:本批改动触及 `game/`(游戏工程代码、测试、探针、场景)→ `--code`;不触及 `game/` 的一切改动(`design/`、根规则文件、`tools/` 工具脚本、`.zcode/` 配置等)→ `--docs`;同批混触 `game/` 与文档面 → 全量档不带参数。所选域全绿才合回 master。该脚本是全部验证闸的**唯一入口、唯一清单与唯一域划分**,闸件增减、分域调整都只改它;**本文与其他文档禁另列闸件清单**(清单散落多处正是 iter27 漏跑 `probe_gate --full` 的成因)。跑完写回执 `game/tests/.gates/receipt.json`(含 `domain` 字段),合回时由 worktree-guard 按 diff 路径推域强制校验(五况拦截:缺回执/quick 模式/回执 commit ≠ HEAD/域不覆盖本次改动/含新增红)。闸件(`tools/` 下机检脚本与闸壳)自身的改动不占合回全量——其质量义务=落批时的变异验证(test-conventions §6),闸真崩溃时合回闸 fail-closed(跑不出回执即拦),不以合回全量为兜底 +10. **批末按域验收才合并**——在任务 worktree 内跑 `tools/run_all_gates.sh`,**按本批改动域选档**:本批改动触及 `game/`(游戏工程代码、测试、探针、场景)→ `--code`;不触及 `game/` 的一切改动(`design/`、根规则文件、`tools/` 工具脚本、`.zcode/` 配置等)→ `--docs`;同批混触 `game/` 与文档面 → 全量档不带参数。所选域全绿才合回 master。合回前独立验收审计通过(iter 技能第 5 步),未过不合回。该脚本是全部验证闸的**唯一入口、唯一清单与唯一域划分**,闸件增减、分域调整都只改它;**本文与其他文档禁另列闸件清单**(清单散落多处正是 iter27 漏跑 `probe_gate --full` 的成因)。跑完写回执 `game/tests/.gates/receipt.json`(含 `domain` 字段),合回时由 worktree-guard 按 diff 路径推域强制校验(五况拦截:缺回执/quick 模式/回执 commit ≠ HEAD/域不覆盖本次改动/含新增红)。闸件(`tools/` 下机检脚本与闸壳)自身的改动不占合回全量——其质量义务=落批时的变异验证(test-conventions §6),闸真崩溃时合回闸 fail-closed(跑不出回执即拦),不以合回全量为兜底 11. **合并后主区按域复跑**——合并可能引入冲突或环境差异,落回 master 后按本批改动域复跑:触及 `game/` 的批=全量复跑(维持);纯文档域批=复跑文档域档(秒级),不再全量 12. **批次完成后的登记义务**——合回 master 后按 doc-conventions §12.1 推进待办清单条目状态(做完整条删除),涉及迭代编排的在 roadmap 迭代总表与顶部「当前位」节换代——执行入口=项目技能 batch-closure(批后收尾与中间文档退役),跨会话教训写记忆库。批次过程与结论由 git 提交信息承载,禁止再写会话状态文件(见 doc-conventions 第 10 节)。`design/` 与根规则文件(`AGENTS.md`/`roadmap.md`/`待办清单.md`/`体验验证清单.md`)实现批禁写,见 §13 13. **文档同步闸(实现批禁写文档)**——实现批**禁写 `design/` 整个目录与根规则文件**,要往外交代的东西一律落 `reports/`:实现报告 `reports/iter-实现报告-<日期>.md`(各卡状态+实机目检总清单+遗留读数义务)、代拍板追认单 `reports/iter-代拍板-<日期>.md`、GDD 反哺点清单 `reports/iter-反哺点-<日期>.md`(每条写清哪个文件哪一节、改成什么、依据是什么)。设计权威文档(GDD/art-bible)**任何批都不直改**:用户在会话中逐点裁决后,由非迭代批(工具/规则/文档批)写入 `design/`(执行入口=doc-design 技能),并把反哺条目从 `reports/` 清掉(吸收即死;退役执行=batch-closure 技能)。机械面文档(roadmap 行/术语表/README 工具注)同样归非迭代批在合并前更新。反哺点未落地期间相关 GDD 节视为待反哺,读前先查 `reports/` 与待办清单;需求卡片必列「关联文档同步面」按两层标注 14. **实机目检归用户,只登记不阻塞**——真人检测项登记进实现报告目检总清单与体验验证清单即完成批内义务;禁把等目检当停工理由或完成前置 15. **中间产物吸收即死**——细则见 AGENTS.md 硬性红线与 doc-conventions 第 11 节 +16. **改动级验收闭合**——写卡期列需求侧对照表,实现期补实际对照表(测试文件:行),每个行为改动做撤销证明;合回前独立验收审计。细则=test-conventions §9 ## 4. 测试执行两入口铁规(细则) diff --git a/design/engineering/test-conventions.md b/design/engineering/test-conventions.md index 917e773f..6215218f 100644 --- a/design/engineering/test-conventions.md +++ b/design/engineering/test-conventions.md @@ -31,10 +31,10 @@ ## 5. 测试函数怎么写——验收清单条目的落码规范 -需求卡片 §7「逐需求点验收清单」每一条都要落成可执行的验证;本文定统一写法,卡里定每批的具体内容(测什么/注入哪里)。写卡期查不出执行载体的条目=不可测,当场呈报,禁拖到实现期。 +需求卡片 §8「改动—验收对照表」每一条都要落成可执行的验证;本文定统一写法,卡里定每批的具体内容(测什么/注入哪里)。写卡期查不出执行载体的条目=不可测,当场呈报,禁拖到实现期。 1. **执行载体五选一,逐条声明**:单元测试(`tests/run_all`)/冒烟断言(`smoke_all.gd` 对应场景段)/场景探针(`smoke/` 下 `*_probe`)/MC 同种子逐项比对/人工核对(仅限无法自动化的纪律类需求点,如命名锁定、数值占位)。行为类条目以自动化载体为主。 -2. **粒度与对应关系**:每条清单条目至少一个自动断言;多条条目可合用一个测试函数。断言失败消息末尾带编号尾缀〔卡短名 Vn〕(如〔秘宝批 V3〕)——断言与卡片清单可互相 grep 查找。 +2. **粒度与对应关系**:每条清单条目至少一个自动断言,且断言必须从该条目的真实入口进入;多条条目可合用一个测试函数,但撤销对应改动时每条都要能单独变红。断言失败消息末尾带编号尾缀〔卡短名 Vn〕(如〔秘宝批 V3〕)——断言与卡片清单可互相 grep 查找。 3. **断言词汇按验证对象五选一**: | 词汇 | 适用场景 | @@ -52,6 +52,8 @@ 测试绿只证明「当前代码没犯这个错」,不证明「犯了这个错会被抓住」。新增或改写的验收函数(冒烟断言/探针自检/闸机判据)必须配一次变异验证,把拦截能力自证一遍。**无变异红记录的断言不写「已验收」,只写「已实现,拦截能力未证」。** +行为改动的撤销证明见 §9.4。新增或改写断言用变异验证;修改既有行为用撤销证明。两者不互相代替:变异证明断言能抓这一类缺陷,撤销证明断言真的钉在这次改动上。 + **操作四步(逐条落实现报告变异验证记录表)**: 1. **注入**——把被测件改坏成该类缺陷的最小形态(翻装配序、注释一行 `add_child`、把状态源取反、把层 `visible` 置 false)。一次只注入一处;可直接改源码,不必留长期开关。 @@ -84,3 +86,60 @@ - **脚本错误会静默中断所在函数的剩余断言,而套件仍报全绿**(机制事实):GDScript 无脚本错误陷阱 API,错误不改进程退出码、不计失败数。三处实证:①2026-09-19「309 项 0 失败」实为断言未跑全(状态记录 83);②敌人表行集纪律 10 条断言因定型数组赋值错误从未执行(迭代 29 修复后两条正向见红=夹具本缺锚行);③`Callable` 形参类型写错致解析函数返回 null、后续断言整段蒸发。 - 由此产生两条义务:**写闸件**按 §7 配三硬闸;**写验收函数**必须自证断言全数执行——变异验证(§6)为主证,反例实证(构造缺陷态改前判绿/改后判红)与零命中自检(扫描面为空即判红)为辅证。 - **覆盖率不是目标**:行覆盖率度量缺失(Godot 无内建,第三方属新基建,是否引入待办清单在册待裁);现行补洞=零指名单测清单+人工判定,判定可靠性靠上列自证手段,不靠覆盖率数字。 + +## 9. 改动级验收闭合(2026-10-21 立) + +### 9.1 验收单位是行为改动 + +一个行为改动 = 新增或修改一条函数、一条数据、一处接线、一个生命周期行为、一条玩家可见文案。纯改名、注释、格式化不算行为改动,但必须在对照表里单独列一行写「非行为改动」及判断依据。禁止用「重构」两个字把行为改动藏起来。 + +### 9.2 四层与真实入口 + +- **单元**:不依赖场景树和真实宿主的纯逻辑;测试直接调用被测函数。 +- **接口**:模块边界的公开契约——数据表加载、存档与断点、事件载荷、命令接口;测试从公开入口进出。 +- **集成**:跨宿主的接线、持久、生命周期——例如 LevelRunner 把 level_counters 传给 BattleOrchestrator、两场战斗共享同一个桶、断点续玩;测试必须实例化真实宿主链,禁止用裸 EffectEngine 代替。 +- **探针/golden**:玩家可达性与观感;真实实例化场景、驱动真实输入。 + +分层不是形式。改动发生在哪一层,验收就必须从那一层的真实入口进入。测试绕过了改动点,就不算这个改动的验收——这正是「断言存在、接线坏了却不红」的来源。 + +### 9.3 改动—验收对照表 + +需求卡片列需求侧对照表;实现报告列实际对照表。每行至少六格: + +| 需求点 | 改动(文件:行/行为) | 验收测试(名称+文件:行+尾缀) | 层级 | 真实入口 | 撤销或变异证明 | +|---|---|---|---|---|---| + +实现报告另加「结果」格(绿/红/未过及依据)。两端都要对上: + +- **正向**:每个需求点至少一行;每行必须有真实入口和证明方式。缺任一项=该需求点未验收。 +- **反向**:diff 里每个行为改动至少一行;没有对应行的改动,必须写明「非行为改动」或「由第 X 行覆盖」。 +- **测试侧**:新增或改写的每条断言至少挂一行;挂不上的孤儿断言删掉或补挂到需求点。 + +### 9.4 撤销证明 + +- **修改既有行为**:只撤销该改动(回退该 hunk 或该处接线)→ 跑能覆盖它的最窄测试 → 对应断言必须变红 → 还原 → 复绿。 +- **新增行为**:用 §6 的变异办法把新代码改坏成最小缺陷形态 → 对应断言必须变红。 +- **撤销后仍然绿**:说明断言没钉在这个改动上,判缺漏;不得用「代码能跑通」代替。 +- 每张任务卡至少一条撤销或变异记录;持久化、生命周期、存档、跨战共享这类接线逐行做。 + +### 9.5 禁止削弱测试 + +实现期不得为了让测试变绿而删除断言、放宽阈值、缩小扫描面、把真实入口换成下层直调。确需改判据=需求卡片没写清=上游缺陷:停该卡、呈报退回写卡段,不在实现期自行决定。卡片可预先声明允许改动的旧断言及理由;未声明的削弱由独立审计判红。 + +### 9.6 测试时机 + +不要求 TDD,不要求先红后绿。允许实现后补测试;但补的测试必须通过 §9.4 的撤销证明。实现完再补、补完就绿,不算验收。 + +### 9.7 独立验收审计 + +合并前由没有参与实现的会话或子代理做一次审计。审计只读需求卡片、实际对照表、diff、测试文件和实现报告,自己跑最窄测试抽查,不采信报告里的「已全绿」。审计至少做三件事: + +1. 逐行核对对照表:测试存在、真的执行、尾缀能 grep 到、真实入口没有绕过改动点; +2. 抽查撤销证明:每张任务卡至少一条,按记录复现红/绿; +3. 检查测试削弱:删除断言、放宽阈值、缩小扫描面、换下层直调,逐处要卡片申报或用户批准。 + +审计报告落 `reports/iter-验收审计-<日期>.md`,逐行写「通过/缺漏/例外及依据」。未通过不得合并。测试执行两入口铁规不变:审计在迭代 loop 内启动的子代理算 loop;另开会话须用户点名。 + +### 9.8 生效与旧卡 + +本规自 2026-10-21 起对文件名日期不早于该日的需求卡片生效;旧卡不回头改。旧卡在开工前缺对照表的,由写卡段补,补完再开工。 diff --git a/reports/README.md b/reports/README.md index 7efc21c6..15e1e379 100644 --- a/reports/README.md +++ b/reports/README.md @@ -10,6 +10,7 @@ | `iter-实现报告-<日期>.md` | 各任务卡状态、实机目检总清单、遗留读数义务 | 迭代批 | | `iter-代拍板-<日期>.md` | 批内 agent 替你拍的决定清单,等你追认或推翻 | 迭代批 | | `iter-反哺点-<日期>.md` | 需要写进 `design/` 权威文档的点,逐条列清"哪个文件哪一节、改成什么、依据是什么" | 迭代批 | +| `iter-验收审计-<日期>.md` | 独立验收审计结果:逐行对照表核对、撤销证明抽查、未过项与例外及依据 | 独立审计方(未参与实现) | | `iter-<交付物名>-<日期>.md` | 需求卡片点名的其它交付物(例:`iter27-探针迁移对照-2026-10-14.md`=11 个探针的成员依赖面清单,已随迭代 27 收尾退役) | 迭代批 | ## 不放什么 @@ -23,4 +24,4 @@ 一个迭代号一组文件,落档即死:反哺点被 `design/` 吸收后,对应文件删除,历史进 git commit log (与"历史决策记录只进 git log、不设决策文档"这条红线同口径)。退役执行=batch-closure 技能 -(批后收尾与中间文档退役),删前先过 doc-conventions §11 判据。 +(批后收尾与中间文档退役),删前先过 doc-conventions §11 判据。验收审计报告随实现报告同批退役(结论已并入实现报告)。 diff --git a/tools/pipeline_gate.py b/tools/pipeline_gate.py index 04145dd8..b1a9911a 100644 --- a/tools/pipeline_gate.py +++ b/tools/pipeline_gate.py @@ -7,7 +7,9 @@ r"""pipeline_gate.py — 工作流程流水线闸(待办清单条目状态机 历史行「—」豁免/周期≤2 周可特批豁免/单元格白名单/零命中);「已编迭代↔已写卡段↔迭代行 卡片列」交叉核只此一处。2026-10-18 卡片冲突修订批补两条卡片机检:C1 关联文档同步面的 文档义务口径(生效 2026-10-17)、C2 设计事实源声明(生效 2026-10-18)——两条都按文件名 - 日期只追新规生效日之后的卡,旧卡属 git 历史留档不回头改。 + 日期只追新规生效日之后的卡,旧卡属 git 历史留档不回头改。2026-10-21 验收闭合批补 C3: + 改动—验收对照表的结构检查(生效 2026-10-21)——只查节/列/行/必填格非空,不判断覆盖真假; + 覆盖真假由独立验收审计判。 约束:每红项一行「文件:行号 判据名 一句白话说明」,exit 0=全绿 / 1=有红 / 2=输入件缺失; 卡片与报告存在性相对 --repo-root 解析(缺省=本文件上两级);待办清单与 roadmap 均已为新格式 (2026-10-18 数据整改批),本闸已注册进 tools/run_all_gates.sh 文档域(08c 流水线闸)。 @@ -47,6 +49,12 @@ SOURCE_MARKS = ("设计事实源", "唯一事实源") # 两种合格写法, SYNC_HEADING_RE = re.compile(r"^#{2,3}\s*\d*\.?\s*关联文档同步面") BANNED_DOC_MARKS = ("design/", "../gdd/", "../registry/", "../research/", "../qa/", "../engineering/", "../ux/", "../art/", "roadmap.md", "AGENTS.md") +# C3 改动—验收对照表(2026-10-21 验收闭合批,生效 2026-10-21) +LEDGER_RULE_DATE = (2026, 10, 21) +LEDGER_HEADING_RE = re.compile(r"^#{2,4}\s*.*(验收对照表|改动[—\-]验收)") +LEDGER_REQUIRED = ("需求点", "改动", "验收测试", "真实入口") +LEDGER_PROOF_MARKS = ("撤销", "变异", "证明") +AUDIT_MARK = "验收审计" DATE_RE = re.compile(r"\d{4}-\d{2}-\d{2}") VER_RE = re.compile(r"[vV]\d+(?:\.\d+)*") @@ -411,13 +419,88 @@ def card_date(path): return tuple(int(x) for x in found[-1].split("-")) +def check_ledger(text, path, issues): + """C3 改动—验收对照表结构检查(生效 2026-10-21)。 + + 只查:对照表节在不在、表头有没有五个必需列、有没有数据行、必填格空不空。 + 不判断测试是否真的覆盖改动——那是独立验收审计的职责,机器闸不猜语义。 + """ + lines = text.splitlines() + start = None + for i, raw in enumerate(lines): + if LEDGER_HEADING_RE.match(raw.strip()): + start = i + break + if start is None: + issues.append((str(path), 1, "验收对照表缺失", + "须含「改动—验收对照表」节(2026-10-21 起,req-card §8)")) + return + + header = None + header_line = 0 + for i in range(start + 1, len(lines)): + s = lines[i].strip() + if s.startswith("#") and not LEDGER_HEADING_RE.match(s): + break + if s.startswith("|") and not SEP_ROW_RE.match(s): + header = row_cells(s) + header_line = i + 1 + break + if header is None: + issues.append((str(path), start + 1, "验收对照表缺表", + "节内未找到表格")) + return + + idx = {} + for name in LEDGER_REQUIRED: + hit = next((k for k, cell in enumerate(header) if name in cell), None) + if hit is None: + issues.append((str(path), header_line, "验收对照表缺列", + "缺「%s」列" % name)) + return + idx[name] = hit + proof_hit = next((k for k, cell in enumerate(header) + if any(mark in cell for mark in LEDGER_PROOF_MARKS)), None) + if proof_hit is None: + issues.append((str(path), header_line, "验收对照表缺列", + "缺「撤销或变异证明」列")) + return + idx["证明"] = proof_hit + + rows = 0 + for i in range(header_line, len(lines)): + s = lines[i].strip() + if not s: + continue + if not s.startswith("|"): + break + if SEP_ROW_RE.match(s): + continue + cells = row_cells(s) + if len(cells) < len(header): + issues.append((str(path), i + 1, "验收对照表缺格", + "列数少于表头(%d<%d)" % (len(cells), len(header)))) + continue + rows += 1 + for name, k in idx.items(): + if k >= len(cells) or not cells[k].strip(): + issues.append((str(path), i + 1, "验收对照表空格", + "「%s」列为空" % name)) + if rows == 0: + issues.append((str(path), header_line, "验收对照表零行", + "表内没有数据行")) + + def check_cards(root, issues): - """C1 文档义务口径(生效 2026-10-17)+C2 设计事实源声明(生效 2026-10-18)。 + """C1 文档义务口径(生效 2026-10-17)+C2 设计事实源声明(生效 2026-10-18) + +C3 改动—验收对照表结构(生效 2026-10-21)。 只检文件名日期达生效日的卡——更早的卡属已实现批次的历史留档,不回头改。 C1 判据:「关联文档同步面」表内,目标格指向 design/ 或根规则文件、而义务格仍写 「随批」者红(2026-10-17 req-card §6 改口径后,这类点只能列 reports/ 反哺点清单)。 C2 判据:全文既无「设计事实源」也无「唯一事实源」者红(两种写法都与库内实态对齐)。 + C3 判据:有「改动—验收对照表」节;表头含需求点/改动/验收测试/真实入口/证明列; + 至少一行;必填格非空;全文含「验收审计」声明。语义覆盖不在此判。 """ dirn = root / CARD_DIR if not dirn.is_dir(): @@ -434,6 +517,12 @@ def check_cards(root, issues): issues.append((str(path), 1, "设计事实源缺失", "须含「设计事实源」或「唯一事实源」声明句(req-card §2 三选一," "GDD 节+版本号/样张+art-bible 版本/工程直入证据指认)")) + if when >= LEDGER_RULE_DATE: + check_ledger(text, path, issues) + if AUDIT_MARK not in text: + issues.append((str(path), 1, "独立验收审计未声明", + "须在卡内写明独立验收审计入口与报告文件(2026-10-21 起," + "test-conventions §9.7)")) if when < SYNC_RULE_DATE: continue in_sec = False diff --git a/待办清单.md b/待办清单.md index 8f45c5ea..0b62cba0 100644 --- a/待办清单.md +++ b/待办清单.md @@ -2,6 +2,14 @@ 本清单是流水线的唯一登记处:要做的事先在此登记一条,随流水线段推进改状态,做完整条删除;各系统文档的「待办」节只留一行指路存根,不再自建条目。条目格式(标题=登记元数据,正文=现状/缺口/归属/状态四属性)与状态机以 [doc-conventions §12.1](design/engineering/doc-conventions.md) 为权威。 +#### 验收闭合规则——下一次迭代实测评估(2026-10-21 登记,来源=审计发现,设计面=工程直入) + +**现状**:2026-10-21 已改工作流技能与规约——[测试规范](design/engineering/test-conventions.md) 新增 §9(改动—验收对照表、真实入口、撤销证明、禁削弱、独立验收审计),[AGENTS.md](AGENTS.md) 硬性红线新增「验收闭合」,`req-card`/`iter`/`batch-closure` 三份技能同步,[流水线闸](tools/pipeline_gate.py) 新增 C3 卡片结构检查。规则文本已落地,还没在真实迭代上跑过。 + +**归属**:下一次迭代的实现批(按新规写卡、施工、审计;实测规则是否抓到缺漏、是否误红)。 + +**状态**:待裁决 + #### UI 贴图重构批——营地与元进度件仍是程序化占位(2026-10-13 登记,来源=审计发现,设计面=美术轨) **现状**:营地的柜台场景贴图目前是程序化画出来的临时形态,没有上贴图。这条债原先只写在美术侧的资产清单里([美术资产清单](design/art/art-assets-checklist.md) 第 134 行与第 175 行,原文注明"营地现为程序化占位,状态记录 121⑧ 口径,排期归 UI 贴图重构批"),2026-10-13 由 UI 美化三层诊断转立本清单专条。规格其实已经定了——烛光黄 `#F6C667` 配木色 `#8A5A34`(见 [美术圣经](design/art/art-bible.md) §4.4),素材来源允许走"通用图标改色复用"这条低成本渠道。 From f2b2558098c02483d41f78e01f5a7e1942c8132b Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 03:51:28 +0800 Subject: [PATCH 48/59] =?UTF-8?q?docs(=E8=BF=AD=E4=BB=A332=E5=8F=8D?= =?UTF-8?q?=E5=93=BA=E5=86=99=E5=85=A5=E6=89=B9):=20=E5=8D=A1=E2=91=A0?= =?UTF-8?q?=E5=8D=A1=E2=91=A1=E4=B8=A4=E4=BB=BD=E5=8F=8D=E5=93=BA=E7=82=B9?= =?UTF-8?q?=E6=B8=85=E5=8D=95=2029=20=E9=A1=B9=E6=8C=89=202026-10-21=20?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=A3=81=E5=86=B3=E5=85=A8=E9=83=A8=E8=90=BD?= =?UTF-8?q?=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 措辞换代:八件 design/ 文档「完美排雷」→「完美封印」(art-bible v3.17);术语表「退役词对照」增行成 S11 词表权威来源 - 闸扩面:tools/doc_term_audit.py 词表加「完美排雷」+扫描域扩 design/art(用户裁 2026-10-21);变异验证=注入见红 EXIT=1、还原回绿 - architecture.md v1.9:effect_engine/orchestrator 行与战斗域装配节改 ctx 形态、架构原则补第 8 条「系统无状态」、flag_missed→seal_missed 两处订正 - 提案 v1.3:§7.7/§7.10.3/§7.10.12 三处依卡片 §12 裁①②订正;sim-data/README 纪律③⑦批次例外登记 - 账面:待办清单增反哺专条×2/重锚批准条目/game/ 域欠账条目,无状态原则条「文档设计已闭合」;体验验证清单增 ㉚ 目检五项 - 代拍板两单 14 条用户全部追认(2026-10-21);文档域闸 --docs 全绿(含 08c 流水线闸 70 条目零红) --- design/art/art-bible.md | 6 +- .../engineering/architecture/architecture.md | 11 ++-- design/gdd/systems/冒险循环/难度曲线与Boss.md | 6 +- design/gdd/systems/战斗循环/地图战斗资源.md | 4 +- design/gdd/systems/战斗循环/战斗结算.md | 16 ++--- design/gdd/systems/战斗循环/战斗表现.md | 4 +- design/gdd/systems/表现与支撑/HUD框架.md | 2 +- design/gdd/ux/battle.md | 6 +- design/gdd/ux/interaction-patterns.md | 3 +- design/gdd/术语表.md | 1 + .../提案-效果引擎无状态化-2026-10-19.md | 15 +++-- sim-data/README.md | 2 + tools/doc_term_audit.py | 8 ++- 体验验证清单.md | 14 +++++ 待办清单.md | 62 ++++++++++++++++++- 15 files changed, 121 insertions(+), 39 deletions(-) diff --git a/design/art/art-bible.md b/design/art/art-bible.md index fb97b0e5..0e9cc4f5 100644 --- a/design/art/art-bible.md +++ b/design/art/art-bible.md @@ -1,11 +1,11 @@ # 美术圣经(Art Bible)— Dungeon Sweeper -> 项目:Dungeon Sweeper(扫雷 × 自动战斗 闯关 Roguelike)· 状态:**第 1–9 节定稿**(§6 环境/§7 UI/§8 资产规范/§9 参考与反参考已于 2026-09-23 v1.8 按 D1/D2/D4/D5 框架成文;D3=§5 角色已于 v1.6 落地、v1.7 抽离独立文档;框架 2026-09-22 用户拍板,原登记于中间产物修订指导,经裁决不入库,明细归状态记录 125);现行为 v3.16,历次修订明细见 git 提交史 +> 项目:Dungeon Sweeper(扫雷 × 自动战斗 闯关 Roguelike)· 状态:**第 1–9 节定稿**(§6 环境/§7 UI/§8 资产规范/§9 参考与反参考已于 2026-09-23 v1.8 按 D1/D2/D4/D5 框架成文;D3=§5 角色已于 v1.6 落地、v1.7 抽离独立文档;框架 2026-09-22 用户拍板,原登记于中间产物修订指导,经裁决不入库,明细归状态记录 125);现行为 v3.17,历次修订明细见 git 提交史 > > **Art Director Sign-Off (AD-ART-BIBLE)**:历次批均 SKIPPED(v1.8 §6–9 补全亦 SKIPPED)— Lean/Solo mode(非 PHASE-GATE;§6–9 已成文,full 门禁签核时机待用户表态) > 风格基调(2026-09-10 用户定稿):地牢题材但**非暗黑风**——轻快明亮的幻想冒险风,全年龄;像素风;角色 2~3 头身 > 参考池(用户审阅选定,三者相融):**Into the Breach**(网格信息分层;雷图棋盘呈现基准 = 其战棋地块质感 × 正俯视角,见 §3.2)× **Moonlighter**(明亮像素地牢质感)× **Peglin**(明快全年龄地牢色彩);参考截图存于 `design/art/references/`(三款×2 张,与点名池一一对应;gungeon 两张经 2026-09-22 裁决退场;正面取/弃与反面条款已成文 §9,反面图证待素材生成后另批增补) -> 约束(2026-09-10 用户强调):本圣经是**纯表现层文档**——明亮轻快是美术风格,不是玩法成分。圣经禁止引入、暗示或预设任何玩法语义,不改变任何 GDD 已锁机制;凡表现层需要玩法钩子才能表达之处(如完美排雷检测、Boss 预警),一律标注「待 GDD 定夺」,圣经只规定"若有,则如何呈现"。GDD 机制与圣经冲突时,机制语义以 GDD 为准,呈现方案以本圣经为准 +> 约束(2026-09-10 用户强调):本圣经是**纯表现层文档**——明亮轻快是美术风格,不是玩法成分。圣经禁止引入、暗示或预设任何玩法语义,不改变任何 GDD 已锁机制;凡表现层需要玩法钩子才能表达之处(如完美封印检测、Boss 预警),一律标注「待 GDD 定夺」,圣经只规定"若有,则如何呈现"。GDD 机制与圣经冲突时,机制语义以 GDD 为准,呈现方案以本圣经为准 > **条款验收标注纪律(2026-10-06 P2-4 用户拍板,全文书写规范)**:条款尾部按三档标注验收方式——**`←机检: <断言>`**(脚本可自动判定)/ **`←目检: <判据>`**(机器测不了,但看什么、算过有明确判据)/ **`←方向性`**(气质与方向原则,不承担验收);**新条款一律按此书写**,存量口号型条款分章补标(约 55%,待办清单挂账「口号型条款机检化批」分章推进、每章交付抽验);数值类条款推荐「**待定现用**」态(现行即执法、修订走登记,释义见 §4.1) --- @@ -83,7 +83,7 @@ ### 2.2 轮末自动战斗结算 -- **主情绪**:延迟兑现的清算爽感——扫雷之因逐行兑现为战果;完美排雷(概念定义与兑付结构见《地图战斗资源》)的高光兑现——结算带高光行,以其为全场喝彩级的最高反馈档 +- **主情绪**:延迟兑现的清算爽感——扫雷之因逐行兑现为战果;完美封印(概念定义与兑付结构见《地图战斗资源》)的高光兑现——结算带高光行,以其为全场喝彩级的最高反馈档 - **色彩性格**:情绪不走明度(§2 禁令),色彩转向金橙主导、饱和拉高;数字色转译为弹道色沿行推进 - **氛围形容词**:酣畅、递进、一气呵成 - **能量**:7/10,随连击爬升 diff --git a/design/engineering/architecture/architecture.md b/design/engineering/architecture/architecture.md index 67cfaeb8..14c641cc 100644 --- a/design/engineering/architecture/architecture.md +++ b/design/engineering/architecture/architecture.md @@ -2,8 +2,8 @@ ## 文档状态 -- 版本:1.8 -- 最近更新:2026-10-17(迭代 27/28 GDD 反哺点写入——新增「呈现层装配与会话生命周期」节(视觉层装配合同/三屏壳/RunScope 生命周期与存活性矩阵/ModalFlow tags 协议)、战斗域现状补结算五段与 RunLedger 四账、初始化顺序补启动后置条件六条,均 2026-10-17 用户裁按推荐案写入;实现实证行读数换代) +- 版本:1.9 +- 最近更新:2026-10-21(迭代 32 卡②反哺点写入——effect_engine 行与战斗域装配节改无状态化 ctx 形态、架构原则新增「系统无状态」条;2026-10-21 用户裁) - 引擎:Godot 4.7.2-stable(GDScript 单语言;2026-09-07 锁定) - 评审模式:solo(`review-mode.txt`,2026-09-12 用户拍板——TD/LP 门禁按 solo 跳过,用户授权架构产出自主推进、迭代期回调) - 覆盖 GDD:现行全集——`design/gdd/` 顶层 00–08 共 9 件 + `systems/` 五域 25 件(排雷循环 4 / 战斗循环 5 / 冒险循环 5 / 跨局循环 5 / 表现与支撑 6)+ `ux/` 8 件;原英文命名 12 份系统 GDD 已全部迁入中文域目录,原「未设计」预留(A5 扫雷秘宝 / C1–C4 / B5 / D3–D6)均已立项成文 @@ -112,8 +112,8 @@ | 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API | |---|---|---|---|---| -| **battle_orchestrator**(B1) | 段序骨架(七段结构冻结)、轮 facts 缓冲、可回放步骤流、[明细行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(15 类行 + 字段分层)、条款③⑤闭合对账、**战斗域全部跨系统调用权**、效果引擎宿主(每战 rebuild/战末 adventure 计数器导出回写)+ 树规则挂点施加面(posture 窗/sense 限次/守侧 flag_missed 发射/聚乘算入账前) | `begin_battle(encounter)`;窗口/刷新意图提交面(扮演 D1);`level_clear()`;步骤流(输出契约) | B2/B3/B4 全调用面(**唯一调用方**);A3 request_refresh 代理 + 回发;A2 install/retire + 三事件订阅;A1 generate(attempt 非 scope 事件);D2 SettlementTable + set_reload_gate | 无(零随机、禁 await——切片 88 冒烟实证可回放) | -| **effect_engine**(核心层——内容数据驱动扩展批 iter17 建域) | 事件/事实/效果类型/算子四词表封闭(迭代 21 T3 扩签:EVENTS 18→19 +flag_missed 标错判定、FACTS +battle_index 关卡域战斗序)+ 树规则合成订阅六键(posture 每关首轮窗/sense 两组限次 counter 闸·domain=adventure 跨战斗持久) | rebuild(每战重建)/dispatch/validate_trigger_row/counters_export·counters_seed | ConfigDB(feats/treasure 行集) | 无(零随机全确定) | +| **battle_orchestrator**(B1) | 段序骨架(七段结构冻结)、轮 facts 缓冲、可回放步骤流、[明细行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(15 类行 + 字段分层)、条款③⑤闭合对账、**战斗域全部跨系统调用权**、效果引擎宿主(每战 rebuild;round/battle 桶为编排器自有字典、经 EffectContext 引用挂载)+ 树规则挂点施加面(posture 窗/sense 限次/守侧 seal_missed 发射/聚乘算入账前) | `begin_battle(encounter)`;窗口/刷新意图提交面(扮演 D1);`level_clear()`;步骤流(输出契约) | B2/B3/B4 全调用面(**唯一调用方**);A3 request_refresh 代理 + 回发;A2 install/retire + 三事件订阅;A1 generate(attempt 非 scope 事件);D2 SettlementTable + set_reload_gate | 无(零随机、禁 await——切片 88 冒烟实证可回放) | +| **effect_engine**(核心层——内容数据驱动扩展批 iter17 建域) | 零运行时可变状态的系统(见「架构原则」条 8):事件/事实/效果类型/算子四词表封闭(迭代 21 T3 扩签:EVENTS 18→19 +seal_missed 标错判定、FACTS +battle_index 关卡域战斗序)+ 树规则合成订阅六键(posture 每关首轮窗/sense 两组限次 counter 闸·adv_ 前缀走冒险桶跨战斗持久) | rebuild(每战重建订阅表)/`dispatch(ctx, event, payload, facts)`/`validate_trigger_row` + 静态计数口 `counter`·`counter_add`·`counter_spend`·`bucket_of`·`counter_id_legal`(计数器读写只经 EffectContext 引用束,无导出/灌入接口) | ConfigDB(feats/treasure 行集)、EffectContext(四桶引用由宿主持有:round/battle 桶归编排器、level 桶归关卡域、adventure 桶归 RunLedger) | 无(零随机全确定) | | **level_runner**(C1-lite,切片已建) | 关卡域生命周期(节点链推进、共享 B4 + HP 携带、关卡末 level_clear) | 节点推进接口;LevelTable(`level.tres`——节点 enum {battle,reward,rest,boss}、末节点必须 Boss、ConfigDB 跨表校验⑧) | B1 begin_battle、B4 grant_node_active、ConfigDB LevelTable | 无 | | **run_structure**(C2) | 冒险/关卡序列、失败重开、**master_seed 唯一接线方** | (契约规范源:`../../gdd/systems/冒险循环/冒险结构.md`) | RngService.set_master_seed、C3/D2 | 无 | | **difficulty**(C3) | DifficultyTable 回填、全部曲线数值调参所有权、战斗期望表(切片 monte_carlo 为工具原型) | 调参输出(经 D2 R1 解析/编排器传递,禁反向调用生成) | ConfigDB、B1 对账输出(调参约束清单)、A1 报告 C | 无 | @@ -122,7 +122,7 @@ ### 战斗域装配现状(迭代 27——2026-10-17 用户裁写入) - **结算五段**:B1 编排器的每轮结算序列拆为 `game/core/settlement/` 五个段类——GrantSegment(①授予段,含封印判定与 counter/grant 助手单点)→ AuraSegment(②增益/减益段)→ CombatSegment(③战斗段)→ DecaySegment(④衰减段)→ VerdictSegment(⑤判定段,返回裁定,终局早退语义留 B1)。段序骨架冻结于 `SettlementTable.segment_order` 语义,B1 退为段序编排+接线;段类可直接 `new()` 单测(`settle_segments_test` 在役)。 -- **RunLedger 四账**:`game/core/run_ledger.gd` 单类持四本共享账——同调充能账/真视使用计数/冒险域计数器/统一冒险加算区。所有权:AdventureRunner 开局构造、全程唯一宿主;LevelRunner 经 `set_run_ledger` 下传装配 encounter;战斗侧(B1)经 `encounter["ledger"]` 拿引用、只走 read/append 原语族。审计 P1-4「共享可变字典跨三层三处可写」由「函数签名上不可见的共享引用」换成签名可见的显式类,时点语义(战末导出/开局回灌)逐字不变。 +- **RunLedger 四账**:`game/core/run_ledger.gd` 单类持四本共享账——同调充能账/真视使用计数/冒险域计数器/统一冒险加算区。所有权:AdventureRunner 开局构造、全程唯一宿主;LevelRunner 经 `set_run_ledger` 下传装配 encounter;战斗侧(B1)经 `encounter["ledger"]` 拿引用、只走 read/append 原语族。审计 P1-4「共享可变字典跨三层三处可写」由「函数签名上不可见的共享引用」换成签名可见的显式类。冒险桶计数器无导出/灌入时点:EffectContext 持 `run_ledger.adventure_counters` 的同一字典引用,引擎静态计数口就地直写,跨战持久随 RunLedger 生灭(2026-10-21 迭代 32 卡②无状态化写入)。 ### 呈现层 @@ -350,6 +350,7 @@ CJK 字体随包发行并设为 theme 默认字体——运行时默认字体无 5. **fail-fast + 零特判**——数据错误一律致命中止(错误数值上线比崩溃更伤);API 非法 = 拒绝 + 诊断不静默;变异零运行时分支(行为差异全部由生成端约束保证)。 6. **依赖单向 + 组合根模式**——层间单向依赖、唯一回边 = A2 事件订阅面;核心写调用唯一发生在组合根;禁上帝对象(切片 1100 行 main.gd 反面案例 → 9 单元拆分)。 7. **呈现层契约成文**——面向呈现的信号载荷必须有成文 schema;模态覆盖层必须有"打开时遮挡物隐藏"场景级断言;场景级 UI 探针测试为标配(切片缺陷 ①②④⑤ 教训沉淀)。 +8. **系统无状态**——效果引擎这类系统零运行时可变状态:数据由宿主对象持有并随宿主生灭,状态按参数传入系统,系统只做判定(立项判据=2026-10-19 用户会话裁定;落地=迭代 32 卡②,2026-10-21 用户裁写入)。系统实例不持计数器——计数器住桶(round/battle/level/adventure 四桶,EffectContext 引用束),桶住宿主。 --- diff --git a/design/gdd/systems/冒险循环/难度曲线与Boss.md b/design/gdd/systems/冒险循环/难度曲线与Boss.md index b95413e4..e0654f48 100644 --- a/design/gdd/systems/冒险循环/难度曲线与Boss.md +++ b/design/gdd/systems/冒险循环/难度曲线与Boss.md @@ -221,10 +221,10 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板 | η 读数 ↔ 模拟画像定义 ↔ 可推理率 ι ↔ min_safe_count/生成尝试上限 | sim 档位、[棋盘生成](../排雷循环/棋盘生成.md) | η 是画像条件量:画像重构即锚漂移,重锚顺带;可推理率三元组既有联动扩一员(2026-10-05 判式换代批新增) | | β 带端点 β_lo/β_hi ↔ D_ref ↔ hero max_hp ↔ AC 折算档(5pp 系数) | [战斗结算](../战斗循环/战斗结算.md) | 带是 D_ref 的函数:换锚(D_ref/max_hp)须全带重推;AC 档值变更改 5pp 系数,同罪(2026-10-05 判式换代批新增) | | 直伤雷三行(6/8/8) ↔ 正向同轴行(heal_minor/pierce_strike/magic_bolt) | [地图战斗资源](../战斗循环/地图战斗资源.md) | **同轴镜像比入对账面**:负向/正向比超出 β 带内推导区间即越带;单边动负向三行今后必须带正向镜像行联合检算(2026-10-05 判式换代批新增——d70f6c3/数值修复批两先例的单边动教训成文) | -| clear_blast 区间(24/40/32) ↔ p_perfect | [地图战斗资源](../战斗循环/地图战斗资源.md) | 完美排雷第二份的补贴基数进封印激励对账;单边动清图奖励 = 变相动封印(2026-10-05 判式换代批新增) | +| clear_blast 区间(24/40/32) ↔ p_perfect | [地图战斗资源](../战斗循环/地图战斗资源.md) | 完美封印第二份的补贴基数进封印激励对账;单边动清图奖励 = 变相动封印(2026-10-05 判式换代批新增) | | 标中强化池权重 ↔ 正向池权重(77 分母) ↔ 关级恒等式奖励占比 [15,40%] | [地图战斗资源](../战斗循环/地图战斗资源.md) | 形态 (b) 专属池重摇启用时生效(现行不启):双池分布变动 = E_dig 与 W 同时漂移,须联合检算 + 恒等式占比复核(2026-10-05 判式换代批新增,条件生效行) | -五条经济契约的对账由[战斗结算](../战斗循环/战斗结算.md)闭合验收;挖掘风险不等式已于 2026-10-05 判式换代批重立(三层口径+β 带+条件二封印溢价——结构层接替与数值层带判读详见行动经济 F1 条款3 推导节),本系统的对账义务转为按 β 带逐 u 检算(常设重跑入口 `tools/clear_dominance_audit.py`,现行 u=3 β=1.17 微破下限登记态);清图支配性已于 2026-09-19 按现行值链重跑、裁决②"非支配设计态"维持(回执见 git 提交 2ca3e20,报告已退役)——判式换代后的全套判值重跑随本系统下一次调参批顺带执行。完美排雷乘数的调参权在本系统。 +五条经济契约的对账由[战斗结算](../战斗循环/战斗结算.md)闭合验收;挖掘风险不等式已于 2026-10-05 判式换代批重立(三层口径+β 带+条件二封印溢价——结构层接替与数值层带判读详见行动经济 F1 条款3 推导节),本系统的对账义务转为按 β 带逐 u 检算(常设重跑入口 `tools/clear_dominance_audit.py`,现行 u=3 β=1.17 微破下限登记态);清图支配性已于 2026-09-19 按现行值链重跑、裁决②"非支配设计态"维持(回执见 git 提交 2ca3e20,报告已退役)——判式换代后的全套判值重跑随本系统下一次调参批顺带执行。完美封印乘数的调参权在本系统。 元进度接口预留:**结论——元进度解锁对难度的影响,以生存链区间的平移换算率接入;接口启用形态已定稿(2026-09-18 元进度定稿批,用户拍板):永久强化影响折算为通关率带平移量,判读口径不变;换算率表首版三行(生命上限 / 基础攻击 / 护甲等级——护甲行强条目,验收读数须按解锁后参数重测)与键结构见 `data/schemas/meta_table.gd`,数值行读 `data/tables/`、标定随元进度设计批。** 元进度数值行落地前,本系统不为它预留任何数值行。 @@ -310,7 +310,7 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板 |---|---|---| | 血量锚比率 r_boss | [0.5, 1.1];加难走廊 [1.1, 1.35](扫描已执行,见「Boss 设计」节) | Boss 生命锚;**锚漂移登记(迭代 5 基线重测批)**:数值设计批 Boss 血轴拔高后 L2/L3 现值 r_boss≈0.33(全行集 Σ 口径)低于域下限 0.5——该指向已过期(迭代 5 已关闭未执行);r_boss 复算与收锚义务挂起,随数值批重开时核销 | | 克制矩阵 | 克制 / 中性 / 被克三档加法修正(+1/0/−1 点),读 `settlement.tres` 甲效表 | 消费归[战斗结算](../战斗循环/战斗结算.md) | -| 完美排雷乘数 | 读表 | 调参权本文 | +| 完美封印乘数 | 读表 | 调参权本文 | | 当量参考敞口 | 读表 | 变更触发全量对账重跑 | | 注入概率初值 / 衰减 | 读表 | 注入机制归[地图战斗资源](../战斗循环/地图战斗资源.md) | | 清障炸药威力区间 | 读表 | 清图槽当场引爆 | diff --git a/design/gdd/systems/战斗循环/地图战斗资源.md b/design/gdd/systems/战斗循环/地图战斗资源.md index a0c1443f..2a6e52be 100644 --- a/design/gdd/systems/战斗循环/地图战斗资源.md +++ b/design/gdd/systems/战斗循环/地图战斗资源.md @@ -152,7 +152,7 @@ ### 清图奖励对象:整图封装,可配置可替换 -清图奖励不属于任何一格的格面资源——它是作用域为整张板的独立奖励对象:把一张图的雷全部清完(全部安全格开完)时结算发的那一份。装板摇号时与格子资源同批判尾摇定身份;清图批兑付恰好一次;完美排雷(零误标且至少一次封印标中)追加第二份同身份兑付。 +清图奖励不属于任何一格的格面资源——它是作用域为整张板的独立奖励对象:把一张图的雷全部清完(全部安全格开完)时结算发的那一份。装板摇号时与格子资源同批判尾摇定身份;清图批兑付恰好一次;完美封印(零误标且至少一次封印标中)追加第二份同身份兑付。 它是可配置可替换的封装:数据面上是清图池里的一行(现行默认槽 clear_default),换行即换内容,机制零改动。按图类型差异化已留结构位——`clear_<图类型>` 命名空间预留,不同地图类型可以配不同的清图奖励;词表现行 = {dungeon, underdark, deep_underdark}(2026-09-19 定稿两值、第三关内容批 2026-09-20 增 deep_underdark,玩家侧「地图类型」),差异化内容启用随内容批。 @@ -191,7 +191,7 @@ 1. 战斗结算装上新图后、玩家开挖前调用一次摇号:全部非封锁格的资源类型与清图对象身份摇定,映射进入只读。 2. 玩家挖掘:挖开的格子当场揭晓类型身份;已开格的身份随时可读。 3. 轮末授予段按极性矩阵逐格兑付:正向 percent 挂状态、heal 正向当场结算,非伤害负向当场兑付;伤害形态正负单据暂存,战斗段末统一落地。 -4. 清图轮兑付清图奖励对象,恒非空;完美排雷追加第二份。 +4. 清图轮兑付清图奖励对象,恒非空;完美封印追加第二份。 5. 战斗结束:整图映射退役。换图按新板重摇。 ## P1 / P2 后置 diff --git a/design/gdd/systems/战斗循环/战斗结算.md b/design/gdd/systems/战斗循环/战斗结算.md index 9e7c6faf..cb83ae32 100644 --- a/design/gdd/systems/战斗循环/战斗结算.md +++ b/design/gdd/systems/战斗循环/战斗结算.md @@ -82,7 +82,7 @@ | 蓄力行 | 敌人本拍蓄力不动手(攒下一击)时记一行 **(2026-09-16 敌人技能池批改型为施放行 `cast`:敌人本拍施放增益技——0 伤害动作、具名技能、不掷不折〔原"不兑付伏击"读怪奖励语义随 2026-09-20 八型批伏击退役作废〕;蓄力语义改写为纯攻击增益技,见[敌人系统](敌人系统.md))** | | 衰减行 | 到期临时效果移除一行 | | 判定行 | 胜 / 负 / 继续各一行;终局判定行同时是胜负画面的数据锚 | -| 高光行 | 完美排雷成立时一行,只记实际有效兑付 | +| 高光行 | 完美封印成立时一行,只记实际有效兑付 | 每行还携带公共字段:来源类别、来源格、轮次、显示名、数值,以及可空的高光标记(用于强调封印标中、清图奖励这类值得高亮的结果)。没生效也要留痕:两类"未生效"行如实记录合法例外,呈现时聚合计数,不逐行刷屏。 @@ -105,7 +105,7 @@ ``` flat 类(直伤、治疗、行动点): E = 表值本身 percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × 参考敞口 -完美排雷的清图奖励: E = 奖励表值 × 完美乘数 ÷ 100 +完美封印的清图奖励: E = 奖励表值 × 完美乘数 ÷ 100 ``` | 变量 | 含义 | 现行值 | @@ -113,7 +113,7 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × | E | 效果折算当量(主角生命点) | — | | 参考敞口 | 折算百分比效果所用的代表性伤害敞口,配置值 | 读 `settlement.tres` equivalence_ref_damage(provisional) | | 层数 × 行值 | 单条效果的叠层数与行值,读[增益状态](增益状态.md)的实例数据 | 行值归该系统 | -| 完美乘数 | 完美排雷给清图奖励的乘数,配置值 | 读 `settlement.tres` p_perfect(现行值读表) | +| 完美乘数 | 完美封印给清图奖励的乘数,配置值 | 读 `settlement.tres` p_perfect(现行值读表) | **gp / ap 当量口径注记(2026-10-05 判式换代批 T3——口径空白登记)**:上式 flat 类枚举(直伤、治疗、行动点)不含 gp——现行对账按 **gp 当量 = flat power 代理**计(GP 袋 3 / 破财 2,方案报告假设 A5);ap 当量 = flat 表值 1,机会成本口径(+1AP ≈ 多挖一格 ≈ E_dig + 进度 + 信息价值)更高,差异仅登记不进主算(假设 A6)。gp 的精确口径应经商店定价换算(1 GP 的边际属性当量),归状态层/商店批复核后换代。封印溢价兑付(条款3 条件二形态 a,`settlement.tres` flag_hit_premium=125 provisional)按同型正向 ×(1+δ) 兑付——当量换算随同型行口径同步放大,整数量级取整四舍五入(与伤害管线 round_direction=floor 分域,registry 顺带登记)。 @@ -136,9 +136,9 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × |---|---| | 挖格批 | 开到的安全格逐格兑该格资源的正向(封印格直挖除外——四情况④零奖励);开到的危险格逐格兑该格资源的负向(封印危险格照常——四情况②) | | 封印判定批 | 标中则兑该危险格资源的正向,每颗雷的资格只兑一次;标空则记"封印未中"归因行,并兑该安全格资源的负向 | -| 清图批 | 清图奖励对象恰好发一次;完美排雷追加第二份同身份兑付 | +| 清图批 | 清图奖励对象恰好发一次;完美封印追加第二份同身份兑付 | -授予段当场只兑非伤害形态(增益、治疗、行动点、GP 缓冲、警觉加层);**伤害形态兑付(爆裂、直伤、反噬)以伤害单据暂存,攒到战斗段末统一结算**(2026-10-06 用户裁——地图伤害账殿后,见[伤害单据与伤害控制器](#伤害单据与伤害控制器所有伤害走同一道门)与战斗段两节)。暂存单在授予段按「将兑付」回报——授予段内依赖兑付读数的流程决策(完美排雷第二份、高光份数)依据开单时点事实判定,该时点敌人存活有保证;战斗段末实际结账若目标已灭,控制器自记「奖励未生效」行。 +授予段当场只兑非伤害形态(增益、治疗、行动点、GP 缓冲、警觉加层);**伤害形态兑付(爆裂、直伤、反噬)以伤害单据暂存,攒到战斗段末统一结算**(2026-10-06 用户裁——地图伤害账殿后,见[伤害单据与伤害控制器](#伤害单据与伤害控制器所有伤害走同一道门)与战斗段两节)。暂存单在授予段按「将兑付」回报——授予段内依赖兑付读数的流程决策(完美封印第二份、高光份数)依据开单时点事实判定,该时点敌人存活有保证;战斗段末实际结账若目标已灭,控制器自记「奖励未生效」行。 **充能已退役(2026-09-19 用户拍板)**:原"挖格/标中旗给充能计数 → 战斗段折算穿刺/魔法分量"的弹药系统整体移除——主角攻击回归单分量,克制策略归冒险前配置(主角 attack_type 表值,营地换型 = 改字段;未来冒险前参数面承接策略位)。攻防两条抽象分离纪律保留:攻击类型是伤害的属性轴,棋盘事实只是奖励触发源。 @@ -158,7 +158,7 @@ percent 类(每结算、每层): E = |层数 × 行值| ÷ 100 × 标错的惩罚不再是独立机制:标空封印(标了但格不是雷)= 该安全格格面资源的负向兑付(极性矩阵的"标错"分支),类型化、确定性、零额外派生——旧三选一哈希反噬(暴走 / 失衡 / 伏击+2 三池,坐标×板序号哈希派生)随格面资源批(2026-09-15)整段下线,三池内容收编为 attack / defense / blast 三型的负向行。负向兑付与"封印未中"归因行同键去重,每危险格实例只触发一次;叠层已满授予被拒时记"奖励未生效"行,不静默吞掉。 -完美排雷全有或全无:一张板零误标且至少一次封印标中,清图奖励加倍(现行倍数读 `settlement.tres` p_perfect)。完美计数从装板起算、换图重置;高光行只记实际有效兑付(首份加被接受的第二份),首份即零兑付则高光行不发。封印标中的兑付行自带高光标记,与完美排雷的独立高光行构成两个强制高光检查点。 +完美封印全有或全无:一张板零误标且至少一次封印标中,清图奖励加倍(现行倍数读 `settlement.tres` p_perfect)。完美计数从装板起算、换图重置;高光行只记实际有效兑付(首份加被接受的第二份),首份即零兑付则高光行不发。封印标中的兑付行自带高光标记,与完美封印的独立高光行构成两个强制高光检查点。 举证:兑付数值全部读配置表,本节无新公式;完美乘数的入账换算见收益对照表一节。 @@ -256,7 +256,7 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值 停手与耗尽收轮的回合恒为同图继续;换图指令只允许出现在清图轮,其他轮发换图属于程序错误、立即上抛。秘宝背包以关卡为界:战斗结束不清背包,跨战斗延续;关卡结束时一次性清空,清空前先返回快照计数,作为"剩余秘宝随关卡结束清空"的可见反馈。战斗道具背包已随可选类删除(2026-09-15)下线。(2026-10-09 注:清空对象 = 关卡域库存 treasure_inventory——秘宝过渡形态的机械惰性承载,其投放渠道已随迭代 11 第①批全退役、现行恒空;现行秘宝=营地同调装配件、整局冒险生效不经此域,拆线归实装批——见[秘宝](../跨局循环/秘宝.md)沿革节。) -挖掘期刷新是玩家在挖掘中途主动换图,经[行动经济](../排雷循环/行动经济.md)扣费:扣费成功后按"旧板退役、生成新板、装板、资源预分配恰一次、变异布置"编排,本轮不打断——没有结算段、没有轮次结束。储备不足被拒是玩家决策的合法结果,不是编排错误。刷新图不发清图奖励,完美排雷计数随装板重置。 +挖掘期刷新是玩家在挖掘中途主动换图,经[行动经济](../排雷循环/行动经济.md)扣费:扣费成功后按"旧板退役、生成新板、装板、资源预分配恰一次、变异布置"编排,本轮不打断——没有结算段、没有轮次结束。储备不足被拒是玩家决策的合法结果,不是编排错误。刷新图不发清图奖励,完美封印计数随装板重置。 战斗开始按固定序列开张:关上配置热重载的闸门、打开增益状态容器、掷骰定敌方实际数量、生成敌人、装板并预分配资源恰一次、变异布置([地形变异](../排雷循环/地形变异.md)——棋盘设置顺序第 4 步:生成棋盘 → 打开状态初始化 → 战斗资源格设置 → 变异格设置,消费 `variant_place` 封闭流)、发开轮通知并执行开轮摇号(摇定首轮各敌本拍动作)。上一关的大奖励(如血上限提升)经战斗开始入参的覆盖值通道生效,内容归[冒险结构](../冒险循环/冒险结构.md)。 @@ -339,7 +339,7 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值 - 每事实恰一次:每格受理、每封印判定恰好一次;重复投递不改变结果。 - 极性路由正确:开安全格 / 封印标中只兑正向、开危险格 / 标错封印只兑负向;兑付效果与该格资源类型的字典行一一对应。 - 警觉共享:敌方全体共享同一警觉状态值;blast 负向逐层直授无上限(伏击退役换装——2026-09-20 八型批)。 -- 完美排雷:零误标且至少一面标中时第二份兑付恰一次并发高光行;出现误标或零标中则无高光;计数换图重置。 +- 完美封印:零误标且至少一面标中时第二份兑付恰一次并发高光行;出现误标或零标中则无高光;计数换图重置。 - 开轮摇号:每轮恰摇一次(首轮同样;轮内刷新换图不重摇);摇定后兑现前死亡 → 本拍技能作废(零敌方行动行)、不进冷却不进保底计数;已兑现技能进冷却、保底计数按执行结果更新。 - 战斗段次序:主角先手后逐敌"按摇定技能行兑现、结算伤害、执行上报"各恰一次;主角倒下立即短路,剩余敌人不行动。 - 护甲等级掷点:吃掷点分量(主角基础分量、敌方技能基础伤害分量)逐次掷单骰(骰面读表)——掷点 ≥ 防守方护甲等级 + 攻击加成全额兑付;低掷按缺口查减伤档位表(边界与档值读表),档位不设零档;天然最大面暴击该分量 ×暴击倍率(读表)且恒全额;穿刺/魔法分量与棋盘来源伤害(爆裂、清障炸药、奖励即时)、必中附加分量及增益/妨害施放不掷不折。 diff --git a/design/gdd/systems/战斗循环/战斗表现.md b/design/gdd/systems/战斗循环/战斗表现.md index 7ae83c6c..2c0cfd32 100644 --- a/design/gdd/systems/战斗循环/战斗表现.md +++ b/design/gdd/systems/战斗循环/战斗表现.md @@ -50,7 +50,7 @@ 战斗屏是挖掘与结算两种形态共用的同一张屏:常驻双舞台(白话:战斗画面与扫雷图同屏常驻,像同一块屏上的两个舞台),结算期不切换场景,裁决与理由见 [battle.md 布局决策 1](../../ux/battle.md)。所以战斗表现的工作不是另做一个战斗场景,而是在既有呈现上叠加动画密度与演出——这是本系统范围边界的第一条。 -"发生什么"与"怎么动"因此分了工:敌人死亡是血条归零后灰化加碎裂退场、禁止瞬间消失,结算明细带逐行滚动,完美排雷与封印标中有高光行强调——这些呈现语义已由 battle.md 与 HUD 框架定稿,本文不复述。本文将来承接的只是其上的动画密度:受击反馈、弹道、退场动画等类别。 +"发生什么"与"怎么动"因此分了工:敌人死亡是血条归零后灰化加碎裂退场、禁止瞬间消失,结算明细带逐行滚动,完美封印与封印标中有高光行强调——这些呈现语义已由 battle.md 与 HUD 框架定稿,本文不复述。本文将来承接的只是其上的动画密度:受击反馈、弹道、退场动画等类别。 资产侧同理,这也是双舞台带来的管线约束:若舞台形态悬而未决,同一份角色资产可能因舞台不同而重画。现行解法是剪影跨舞台通用——角色剪影按"棋盘、结算画面与任一战斗舞台通用"设计,不为舞台未决问题付重画成本(art-bible §5.1;原 §3.1,2026-09-22 迁 §5.1)。 @@ -65,7 +65,7 @@ | 奖励未生效行的呈现 | [增益状态](增益状态.md)定稿时登记(数据源是[战斗结算](战斗结算.md)的明细协议) | 让这类行在演出中可读、不被吞掉 | | 效果来源格的可读化 | 同上(候选形态:缩略图或格子高亮,坐标不直接呈现) | 把"效果来自哪一格"翻译成玩家可读的演出 | | 坍塌显形的连锁动画 | [游戏概念](../../00-游戏概念.md)的概念层拍板——坍塌显形是[连锁展开](../排雷循环/排雷玩法.md)的玩家可见名,与音频方向同批配对登记 | 连锁展开触发时的连锁演出 | -| 高光兑现的演出强化 | 完美排雷与封印标中强调的机制及呈现位已由战斗结算与 battle.md 定稿 | 在既有高光行呈现之上加强演出密度 | +| 高光兑现的演出强化 | 完美封印与封印标中强调的机制及呈现位已由战斗结算与 battle.md 定稿 | 在既有高光行呈现之上加强演出密度 | | 伤害数字 | 归档索引中本系统的旧范围一句话即含"伤害数字" | 落点未定:预告上格原则与"敌人不占格、兑现发生在战斗画面区"如何相容,见待设计问题清单 | ### 前置美术测试是硬前置 diff --git a/design/gdd/systems/表现与支撑/HUD框架.md b/design/gdd/systems/表现与支撑/HUD框架.md index 8ce77653..50570a4c 100644 --- a/design/gdd/systems/表现与支撑/HUD框架.md +++ b/design/gdd/systems/表现与支撑/HUD框架.md @@ -274,7 +274,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻 - 一帧内意图整批到达,停手点击终结当帧收集。 - 每次拒绝可感知:棋盘面、资源面、相位三类各有呈现且前两类可区分;停手被改判(本轮已清图)玩家可感知;拒绝反馈图标加文案双通道。 - 结算逐行实时滚出且每行带来源标注;未生效类行聚合计数并带形状冗余;零值行不被吞;效果行的单次贡献与池合成值分示、禁相加误读。 -- 高光三档:封印标中行金框、清图奖励行金框、完美排雷全屏喝彩级——庆祝不打在空兑现上(首份即零兑付则不发高光)。 +- 高光三档:封印标中行金框、清图奖励行金框、完美封印全屏喝彩级——庆祝不打在空兑现上(首份即零兑付则不发高光)。 - 状态槽显示图标加层数加剩余结算次数,悬停见来源;极性按键级表呈现(金满框 / 红缺框),空态整排隐藏、数据框上移补位;战斗结束全清有微文案。 - 敌人呈现(站桩立绘,2026-09-20 全站桩拍板后载体由敌人卡改为无框立绘+底座,义务面平移不重述):意图占位 = 本拍摇定结果的动画占位(敌人技能池批三档可见性——普通攻击零表示、特殊技类型级提示〔攻/防系两型〕,不预告技能名与数值、池与权重不公开)且挖掘期全程可见、映射跨局恒定、顺位可读、血量数字可读、敌方共享层数各立绘同值(血条悬浮头顶、状态小图标挂血条正下方);死亡灰化加碎裂退场(禁止瞬间消失)且就地更新不丢灰化态。 - 终局:胜利金蜡封、失败暮蓝氛围层(明度不变);储备清零与状态全清两反馈不合并、时序不倒挂(关卡末清库反馈义务载体 = 秘宝背包〔关卡域库存恒空机械惰性承载,拆线归实装批——见「轮次生命周期」同款节注于战斗结算〕,随秘宝 P0 落地补验收)。 diff --git a/design/gdd/ux/battle.md b/design/gdd/ux/battle.md index 46fcf67a..cd27e1df 100644 --- a/design/gdd/ux/battle.md +++ b/design/gdd/ux/battle.md @@ -82,7 +82,7 @@ 1. **扫雷图本体**(第一注视点,挖掘期占视觉预算大头):两格态(已开格 / 未开格——排雷玩法×6② 一眼可辨)、数字、封印印记、小人、可挖域(8 向相邻常驻指示)、变异纹理 2. **本轮行动资源**:AP 余量(决定还能挖几格)、RAP 池(弃图刷新货币)、停手/弃图刷新按钮——紧贴棋盘上缘(动作发生地) -3. **战果兑现面**(结算期为第一注视点):敌人血条变化、逐行结算明细、高光(完美排雷/封印标中) +3. **战果兑现面**(结算期为第一注视点):敌人血条变化、逐行结算明细、高光(完美封印/封印标中) 4. **规划面**(边缘注视,常读):攻击值与修正来源(C 区数据框)、敌人意图徽标与顺位(B 区站桩);HP 与状态效果由单位本体(B 区站桩)唯一承载——数据框不重复展示 5. **进度语境**:轮次/阶段指示、图例入口(关卡节点进度常驻关卡画面,战斗屏不承载——见 Navigation Position) @@ -219,7 +219,7 @@ | **挖掘阶段(默认态)** | 轮次开始 / 结算完毕回 Active 相位 | B 区敌人待机(意图徽标全程可见——敌人系统 Rule 8⑤),D 区棋盘可交互,AP 条点亮;能量 2/10,唯悬停呼吸微光在动(§2.1) | | **结算阶段** | round_end 触发(AP 尽/停手/清图) | D 区锁输入(棋盘去饱和 + 金橙色相偏移,明度不变,数字保持全对比);B 区播放五段编排演出(授予段 → 增益/减益段 → 战斗段 → 衰减段 → 判定段,战斗结算 段序冻结);明细带展开 84px 逐行滚动;阶段指示→"结算中";能量 7/10 | | **清图瞬间** | 全部安全格开完 | 金粒喷泉 + 彩纸 3–5s 即收(§2.3);清图奖励行强调呈现(H2,地图战斗资源×④——金框高亮行);随后换新图 install | -| **完美排雷高光** | 战斗结算高光判定(全图标中/零误标类) | 全屏喝彩级反馈(§2.2 最高档):金光带加倍扫射 + 「完美排雷 ×2」横幅——P2 爆发兑现节点(创意风险 #2 落点) | +| **完美封印高光** | 战斗结算高光判定(全图标中/零误标类) | 全屏喝彩级反馈(§2.2 最高档):金光带加倍扫射 + 「完美封印 ×2」横幅——P2 爆发兑现节点(创意风险 #2 落点) | | **封印标中高光** | flag_judged{hit=true} | 该印记化暴击弹道加重 + 明细行金框——chord 缺席的即时兑现补偿(创意风险 #3 落点) | | **敌人死亡呈现** | 敌 hp=0(流水行击杀标记) | 该敌人立绘血条归零 → 立绘灰化 + 碎裂退场(**禁瞬消**——敌人系统资产下限「死亡瞬间须可辨识、禁止直接消失」,同等 blocking);战斗段短路的重击被掐灭不产行动明细行,由行序可推断(战斗结算);动画密度归战斗表现,呈现语义在本 spec | | **胜利终局** | verdict=win | 金蜡封落于**扫雷图区中央**(§2.4 字面锚定),全屏暖白金 overlay;判定行 + 「下一节点」;明细回看入口;状态图标行全清可见反馈(增益状态×4④——B 区主角站桩图标逐枚化光收回 + 微文案「状态随战斗结束消散」,防「我的增益哪去了」误读) | @@ -419,7 +419,7 @@ | 排雷玩法×6 | ⑤ 路径预览裁决 | 布局决策 3 | | 排雷玩法×6 | ⑥ 单意图帧+voided+拒绝可感知 | §Interaction Map + §States 拒绝子态 + AC | | 行动经济 | AP/RAP 常显+刷新入口+清零反馈+双源 | §Layout D 区 AP 条(RAP 自 C 区迁入——2026-09-26 信息归属拍板)+ §Transitions + AC | -| 战斗结算×3 | ①高光行强调呈现(封印标中金框行/清图 H2 金框行)②完美排雷呈现形态 ③棋盘生成 EC5 零合法板提示/补偿/回退形态(toast 提示;补偿/回退不提供——三形态选型留痕 2026-09-12) | §States 高光/清图 + §States 拒绝子态 + §AC;注:结算明细屏 = 战斗结算 UX Flag 事项(本 spec 即其 /ux-design 产物),非 战斗结算×3 状态记录 | +| 战斗结算×3 | ①高光行强调呈现(封印标中金框行/清图 H2 金框行)②完美封印呈现形态 ③棋盘生成 EC5 零合法板提示/补偿/回退形态(toast 提示;补偿/回退不提供——三形态选型留痕 2026-09-12) | §States 高光/清图 + §States 拒绝子态 + §AC;注:结算明细屏 = 战斗结算 UX Flag 事项(本 spec 即其 /ux-design 产物),非 战斗结算×3 状态记录 | | 敌人系统×4 | 意图映射/恒定/顺位/敌方池 | §Component Inventory 敌人站桩立绘 + **意图线索映射目录(敌人系统×4① 成文占位,资产定稿归战斗表现)** + AC | | 增益状态×4 | 常显+空态/来源标注/溢出/去留 | §States 空态 + §AC | | 地图战斗资源×5 | 身份恒读/明细行/清图强调(旧版状态记录五条中「窗口」「清空反馈」随格面资源批下线——清空反馈义务后载秘宝背包、复随秘宝过渡形态退役消解(现行 = 营地同调装配,秘宝.md)) | §Component Inventory BoardView 奖励徽章 + §States 清图/高光 + §Data Requirements query_identity + AC | diff --git a/design/gdd/ux/interaction-patterns.md b/design/gdd/ux/interaction-patterns.md index 584fc018..a314bbf5 100644 --- a/design/gdd/ux/interaction-patterns.md +++ b/design/gdd/ux/interaction-patterns.md @@ -87,7 +87,7 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab - 数据源:[战斗结算](../systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)步骤流(9 类行封闭协议(现行);公共字段 `type/source_class/origin_cell/round_index/display_name/value/highlight?`);**无来源行 = 断言失败** - 行模板:「{行为} {值} → {目标}(来源)」——来源标注(第 N 轮 · 安全格式);行文案最长 token = 来源标签(4 汉字封闭枚举),模板预留 40% 膨胀宽度 - 聚合纪律:未生效类行(奖励未生效——现行 9 类行协议唯一未生效型,2026-09-20 收敛)按聚合计数呈现(防逐行惩罚轰炸);衰减行聚合计数;效果行 value=单次贡献值、禁与 pool_value(池合成值)相加呈现;零值行可见不吞(免伤轮归因不断点) -- 高亮:highlight 字段 {flag_hit, clear_reward_h2, perfect_broken} → 金框强调;完美排雷 = 独立高光行 + 全屏喝彩级反馈。`perfect_broken` 的判据句读作「本板首次标错受检」,不等于完美资格已失——专长「完美保险」可在本场首次标错时豁免,实际资格按有效误标(误标总数 − 豁免数)判定 +- 高亮:highlight 字段 {flag_hit, clear_reward_h2, perfect_broken} → 金框强调;完美封印 = 独立高光行 + 全屏喝彩级反馈。`perfect_broken` 的判据句读作「本板首次标错受检」,不等于完美资格已失——专长「完美保险」可在本场首次标错时豁免,实际资格按有效误标(误标总数 − 豁免数)判定 - 布局:固定槽高 + clip_contents;正文 ≥14px;数值暗底高对比;未生效类行带 icon/划线形状冗余 - 击杀标记呈现(H3 数据源 = 战斗结算流水击杀结果字段) @@ -213,3 +213,4 @@ MVP 未使用标准控件(不入库):toggle / dropdown / input field / tab 2. Gamepad 批次引入时,需为 pattern 4/12/15 增补手柄映射节(焦点序已在 battle.md OQ8 留位) --- + diff --git a/design/gdd/术语表.md b/design/gdd/术语表.md index 98adb74b..26f2ffb8 100644 --- a/design/gdd/术语表.md +++ b/design/gdd/术语表.md @@ -139,6 +139,7 @@ | 巢穴(机制表述) | 危险格(世界观风味层的巢穴隐喻〔00-游戏概念/美术纹样名〕除外) | | 正主 | 现行事实源 | | 落籍 | 已入库 | +| 完美排雷 | 完美封印(2026-10-19 用户裁:全库统一换代,含代码内部注释;玩家面正式名=完美封印,2026-10-21 迭代 32 卡①反哺入表) | | 工作日志 | 状态记录 | | 金币 | GP(2026-10-18 用户裁:GP 是唯一正式命名,「金币」系 AI 噪音全库禁用) | | 插旗 | 封印(2026-10-18 用户裁:封印=正式动作名,全库统一,非比喻非「对外表达」别名) | diff --git a/design/research/提案-效果引擎无状态化-2026-10-19.md b/design/research/提案-效果引擎无状态化-2026-10-19.md index 665dc416..494fc31e 100644 --- a/design/research/提案-效果引擎无状态化-2026-10-19.md +++ b/design/research/提案-效果引擎无状态化-2026-10-19.md @@ -1,7 +1,7 @@ # 提案:效果引擎无状态化(计数器外置·分桶) - **日期**:2026-10-19 -- **版本**:v1.2(2026-10-20 设计闭合版——现行身份标记;改动沿革只查 git commit log) +- **版本**:v1.3(2026-10-21 依需求卡片 §12 裁决订正 §7.7/§7.10.3/§7.10.12 三处口径——现行身份标记;改动沿革只查 git commit log) - **性质**:架构重构提案(restructure,非 refactor)——现役设计被判为错误形态,不是打磨 - **上游**:`design/gdd/06-待办清单.md:627`「计数器寿命域未统一」条目(2026-10-18 登记);本提案推翻该条目的解法方向,见 §8 - **状态**:**设计已闭合·可写卡**——§7 设计定值、§7.7 采集定不发起;§4.3 六项卡点、§4.4 八项实现设计缺口、§4.5 六项需求澄清已于 2026-10-20 复核轮全部闭合(定值与推导依据集中在 §7.10,§3.2/§4.1–§4.5/§5 各节已按定值同步改写);其中 B6(dig_combo 死读数删除)与 §7.9 五条同口径属「约束可推、可否决」项 @@ -292,6 +292,7 @@ round_start 清零点保留在引擎 `dispatch` 特判内(`:210-212` 现役挂 **我把它挂上去的真实动机**是「想确认行为变更不是灾难级」。但这个需求有更便宜且纪律明定的手段:**同种子复放对拍**(配套纪律③——对拍断言 = **0 局新采集**,同种子重放已有锚,出口闸复验用锚内子集 ≤20)。对拍的作用是**排除意外**(除已知几处外不得有其他差异),不是量化。 **定值**:不发起任何档位采集。依据=配套纪律⑦「零数值改动 = 零 MC」+档位表四档触发面均为数值场景。验收=同种子复放对拍,adventure 桶相关差异列为**已知行为差异并记档**,不声称零漂移。§1 完成定义 6 同步改为「除已记档的已知差异外,逐位一致」。 +> **〔卡片裁决订正 2026-10-21,依 §12 裁①〕** 「零采集」前提失效:现行锚与本批采集面不同构,不可作复放基线。定值改为**批内重采三组各 40 局基线+批后同种子复放 40 局**(二档上限内,`sim-data/` 纪律③⑦开批次例外);其余判读口径见 §7.10.12 订正注。 🔴 **必须呈报的事实(削弱幅度)**:`tree_sense_sharp_used` / `tree_sense_guard_used` 修后是**显著削弱**,不是变强。 @@ -459,7 +460,8 @@ func counters_merge_export(exported): #### 7.10.3 A3——前缀校验双落点定值(E2 并入 F1) -**定值**:前缀合法性校验落两处、共用同一静态判定函数——①`validate_trigger_row`(.tres 行路径):`do` 含 `counter_id` 时校前缀(无前缀=合法 battle;`round_`/`lvl_`/`adv_` 合法;`meta_` 及其余未知前缀→errs 追加违例,加载致命);②`_push_trigger`(树合成行路径):同规则 assert,写错即调试期致命。**E2 撤销**:「同 counter_id 跨前缀重复」在新形态下无指称——前缀即归属,同一字符串必落同一桶,「跨桶同名」不可构造;「同一语义计数器两行写了两套 id」(改名漏改一类)不可机器判定(两串本不同),其防线归 F1:静态扫描 S 段新增**带引号旧 id 字面零命中**规则(`"tree_sense_sharp_used"`/`"tree_sense_guard_used"`/`"twin_digs"`/`"instinct_atk"`——带引号匹配不误伤 `"lvl_tree_sense_sharp_used"`/`"adv_twin_digs"`/`"round_instinct_atk"` 等新名)。 +**定值**:前缀合法性校验落两处、共用同一静态判定函数——①`validate_trigger_row`(.tres 行路径):`do` 含 `counter_id` 时校前缀(无前缀=合法 battle;`round_`/`lvl_`/`adv_` 合法;`meta_` 及其余未知前缀→errs 追加违例,加载致命);②`_push_trigger`(树合成行路径):同规则 assert,写错即调试期致命。 +> **〔卡片裁决订正 2026-10-21,依卡片 §12 裁②〕** 前缀判据定值改松版:只禁 `meta_` 前缀,其余(含未知前缀)一律落 battle 桶即归属——`feats.tres` 现有 14 枚 id 全含下划线、首段除三枚 `round_` 外全是普通词,本节严版误伤全部既有 battle id,且封闭前缀词表=第二事实源(2026-10-19 registry 注销裁定同类)。自造新前缀静默落 battle 的残余风险改由装载期引用闭合校验(写读成对核验,拦「字面改一半」)正面承接,不再单靠人工评审;判定函数=`counter_id_legal`。本节其余双落点结构不变。**E2 撤销**:「同 counter_id 跨前缀重复」在新形态下无指称——前缀即归属,同一字符串必落同一桶,「跨桶同名」不可构造;「同一语义计数器两行写了两套 id」(改名漏改一类)不可机器判定(两串本不同),其防线归 F1:静态扫描 S 段新增**带引号旧 id 字面零命中**规则(`"tree_sense_sharp_used"`/`"tree_sense_guard_used"`/`"twin_digs"`/`"instinct_atk"`——带引号匹配不误伤 `"lvl_tree_sense_sharp_used"`/`"adv_twin_digs"`/`"round_instinct_atk"` 等新名)。 **推导依据**:完成定义 5「写错即加载致命」对 .tres 行经 errs→load_tables 拒绝通道成立(feat_table.gd:44/treasure_item_table.gd:104 调用面零改、校验在函数内部生效);树合成行不经 .tres 校验、只在 rebuild 期经 `_push_trigger` 生成(`effect_engine.gd:142-158`),漏②=A3 原判「与完成定义 5 直接冲突」成立。负面套件载体=`reward_dangling_treasure_test.gd` 同构(copy_tables 夹具注入坏行→load_tables 拒→expect 1+negative:true,run_all.gd manifest 登记)。 @@ -499,14 +501,17 @@ func counters_merge_export(exported): #### 7.10.12 U5——G1 已知差异面(分组判读制) -**定值**:RUNSUM 字段面清点完毕(`adventure_monte_carlo.gd:114-149` 共 27 字段)。行为变更只触 adventure 桶四枚中的三枚——**pain_layers 迁 battle 对全新开局零位移**(缺陷态下本就不跨战〔§7.8 自锁〕,battle 桶同样不跨战,前后皆无跨战携带);受影响枚=`adv_twin_digs`(返还得真跨战累积)与 `lvl_tree_sense_*`(每战限 2 → 每关限 2,§7.7 削弱定性)。同种子复放比对判读分两组: +**定值**:RUNSUM 字段面清点完毕(`adventure_monte_carlo.gd:114-149` 共 27 字段)。行为变更只触 adventure 桶四枚中的三枚——**pain_layers 迁 battle 对全新开局零位移**(缺陷态下本就不跨战〔§7.8 自锁〕,battle 桶同样不跨战,前后皆无跨战携带);受影响枚=`adv_twin_digs`(返还得真跨战累积)与 `lvl_tree_sense_*`(每战限 2 → 每关限 2,§7.7 削弱定性)。 +> **〔卡片裁决订正 2026-10-21,依卡片 §12 裁①与本卡〕** 实采字段面为 33 个(本节原记 27 系清点时漏量);分组判读由两组扩为三组——单一「`levels_cleared` 不得上行」判据把增强组(双管镐跨战累积返还得真)与削弱组(sense 每关限 2)混判,作废。现行判读口径=**off 组全字段逐位一致;formed 组与 rules 组输入面字段恒等、其余字段允许 RNG 级联位移、方向只记报告不作判据**。下表按此执行。 + +同种子复放比对判读分组(现行口径): | 组 | 判定条件(由 RUNSUM 自身字段可判) | 判据 | |---|---|---| | 未受影响局 | feat_mode=off,或装备集不含双管镐与 sense 两组 | **全字段逐位一致**(结构迁移对未触路径必须透明——零漂移回归面) | -| 受影响局 | 保守超集:装备集含受影响件且(`mine_hits>0` 或 `seal_miss>0` 或付费挖格≥2) | 输入面字段恒等(policy/seed/atk_pct/hp_pct/route/attune/equipped/feat_mode);其余字段允许 RNG 级联位移(轮数一变后续流消费全移);统计面判据一条:**`levels_cleared` 分布不得上行**(削弱批清关率上移即意外,§7.7 定性) | +| 受影响局(formed/rules 两组) | 装备集含受影响件(formed=表驱动装配、rules=树规则注入,采集分组见卡片 T0/T7) | 输入面字段恒等(policy/seed/atk_pct/hp_pct/route/attune/equipped/feat_mode);其余字段允许 RNG 级联位移(轮数一变后续流消费全移);**方向只记报告不作判据**(增强组与削弱组分列读数随实现报告记档) | -复验规模:锚内 normal 档前 20 种子(81000–81019,配套纪律③子集 ≤20;normal 单局 1.21s,20 局约 25 秒)。逐位差异明细随实现报告记档。 +复验规模(本节原案,作废——现行锚 24 字段面与本批采面不同构、且 `sim-data/` 不入 git 致 worktree 内无锚文件可校):~~锚内 normal 档前 20 种子(81000–81019,配套纪律③子集 ≤20)~~。**现行口径〔卡片裁决订正 2026-10-21,依 §12 裁①〕=批内重采三组各 40 局基线+批后同种子复放 40 局**,二档上限内、`sim-data/` 纪律③⑦的批次例外已按其反哺条登记;现行锚与读数文件一律不动。逐位差异明细随实现报告记档。 #### 7.10.13 U6——`mine_hit` 构造路径 diff --git a/sim-data/README.md b/sim-data/README.md index 91e46246..34d22878 100644 --- a/sim-data/README.md +++ b/sim-data/README.md @@ -27,6 +27,8 @@ 配套纪律:①档位上限=硬闸,超档停机呈报;窗口不足如实挂起(禁在二/三/四档下带值结论);②改前/改后锚**同 seed0 配对**、改前锚留盘即用禁补跑;③对拍断言=0 新跑(同种子复放,出口闸复验用锚内子集 ≤20);④读数缺陷≠轨迹失效——零 gameplay/RNG 触碰的修复走事件流重构补算,禁整套重跑;⑤同批同码态锚只取一次,「调整一下就重跑」禁止;⑥会话累计:二/三/四档合计 ≤20 分钟(一档时长随用户发起确认);⑦零数值改动=零 MC(现行铁规重申);⑧锚文件自本规起新锚统一=去前缀纯 JSONL、按种子升序(81000 旧形态带 RUNSUM 前缀+进度行,analyze.py 直读会炸),批耗时随锚记 active.md 台账。 +**批次例外登记(2026-10-21,依迭代 32 卡②反哺条 2026-10-20 用户裁)**:迭代 32 卡②(效果引擎无状态化)对纪律③⑦开一次批次例外——V12 同批内重采 formed/rules/off 三组各 40 局基线+批后同种子复放 40 局(合计在二档 ≤40 局上限口径内,依据=现行锚 24 字段面与本批 33 字段面不同构、不可作复放基线,卡片 §12 裁①);现行锚与读数文件一律未动、不改名、不替换,采集文件留盘供报告与后续核对。 + 四档仅承接 MC 触发细则的数值验证场景,两入口铁规不变。 ## 工具与格式 diff --git a/tools/doc_term_audit.py b/tools/doc_term_audit.py index 28e54004..9ba0c203 100644 --- a/tools/doc_term_audit.py +++ b/tools/doc_term_audit.py @@ -14,8 +14,9 @@ r"""doc_term_audit.py — GDD 退役术语扫描(半自动) python tools/doc_term_audit.py ... # 只扫指定文件 python tools/doc_term_audit.py --json # 机器可读 -口径:只扫 design/gdd/——design/research -(历史提案)、docs/(样例)与 production/ 不在扫描域;词表扩充 = 改 RETIRED_TERMS。 +口径:扫 design/gdd/ 与 design/art/ 两处文档域(2026-10-21 迭代 32 卡①反哺批扩面 art, +用户裁)——design/research(历史提案)、docs/(样例)与 production/ 不在扫描域; +词表扩充 = 改 RETIRED_TERMS(受 doc-conventions §4 词表冻结约束:唯一入口=用户实读反馈并经用户裁决)。 """ import argparse import json @@ -66,9 +67,10 @@ RETIRED_TERMS = [ # (词面误报率高,靠术语表对照行与人工判读),game/ 扫描域归代码批后另加。 ("金币", "2026-10-18", "GP(唯一正式命名)", "GP 命名统一批——「金币」全库禁用"), ("插旗|标旗", "2026-10-18", "封印(正式动作名,全库统一)", "术语刷新批——「旗」概念退役"), + ("完美排雷", "2026-10-19", "完美封印(正式名见 design/gdd/术语表.md 退役词对照)", "迭代 32 卡①反哺批 2026-10-21 用户裁入表——代码注释面由 S11 承接,文档正文面由此条承接"), ] -DEFAULT_DIRS = ["design/gdd"] +DEFAULT_DIRS = ["design/gdd", "design/art"] # 用语规范 A 表补充词专项补扫:随批/台账 两词本身是上方行级白名单信号(行内出现即归 # 留档类),主扫描对它们自豁免;本通道只做节外残留的专项报告,供后续触碰批清偿。 diff --git a/体验验证清单.md b/体验验证清单.md index 2919f5a8..60ab2871 100644 --- a/体验验证清单.md +++ b/体验验证清单.md @@ -318,3 +318,17 @@ | 5 | 完美保险卡面文案 | 专长卡面文案读作「本场首次封印落空,不计入完美封印判定」,零「雷」字 | | 6 | 稀有档三选一 | 三选一带不再出现同调电池/完美保险;稀有档仅剩 ap/rap/time_sand 三种 | | 7 | 豁免后的完美第二份 | 带完美保险专长时,首次标错后清图仍能拿到「完美第二份」(订阅式豁免的实际观感) | + +--- + +## ㉚ 迭代 32 卡①/卡②——玩家可见文案与限次观面目检(2026-10-21 随反哺写入登记) + +> 卡① 换代对外文案(「完美排雷」→「完美封印」)并修正归因锚判据(N7——豁免累加时点与有效误标判据);卡② 把天赋树锋/守限次从每战 2 次改为每关 2 次(玩家可感知削弱)。机检能证明词面换代与两态判定同真值一致(冒烟 A10–A12 与单元断言),行序呈现与实际手感仍要人眼看。登记不阻塞(2026-10-12 真人检测立规)。 + +| # | 目检项 | 判据 | +|---|---|---| +| 1 | 结算明细两行先后 | 「完美保险·标错豁免」行先于「封印未中」行呈现(豁免在前、未中不带金框) | +| 2 | 未豁免态文案 | 无保险首次标错的「封印未中」行带金框,文案「本图完美封印已破——清图奖励不再加倍」可读 | +| 3 | 高光行与横幅 | 对外高光行「完美封印!清图奖励 ×2」与全屏横幅「完美封印 ×2」显示正确、零「雷」字 | +| 4 | 天赋树锋/守限次 | 同一关内第 3 次起踩危险格不再伤害减半、第 3 次标错不再返还行动点(每战限 2 → 每关限 2 的实际手感) | +| 5 | 旧档续玩 | 含改名前 counter 键的旧断点存档正常进入不崩(崩溃面已由 V13 自动化覆盖,此处目检手感) | diff --git a/待办清单.md b/待办清单.md index 8f45c5ea..7cc883f1 100644 --- a/待办清单.md +++ b/待办清单.md @@ -695,6 +695,8 @@ 需求卡片:reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md(v1.3)。 +反哺写入与代拍板追认结果见本清单「迭代 32 卡① 反哺点写入」条目(2026-10-21 文档批)。 + **归属**:game/ 代码与数据表(代码域,走独立 worktree 批;`AGENTS.md` 与 `design/` 依流水线红线本批禁碰,S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`) **状态**:已写卡+已编迭代 32 @@ -703,13 +705,13 @@ #### 效果引擎「系统无状态」原则缺架构文档条目(2026-10-20 登记,来源=会话提及,设计面=文档轨) -**现状**:用户 2026-10-19 会话裁定的 ECS 架构依据(系统无状态——效果引擎这类系统零运行时可变状态、数据由宿主对象持有并随宿主生灭、状态按参数传入系统、系统只做判定)是「效果引擎无状态化」重构批的立项判据(上游条目=本清单「计数器寿命域未统一」,提案=design/research/提案-效果引擎无状态化-2026-10-19.md §7.9 #1),但 `design/engineering/architecture/architecture.md`「架构原则」节(现行 7 条)无「系统无状态」条目——立项判据暂无权威文档出处(2026-10-19 全仓检索「无状态/纯计算」零命中,提案 §10.3 实查;原 `design/registry/` 两 yaml 已随 2026-10-19 用户裁注销删除,无可迁凭据)。重构批是代码批、禁写 `design/`,文档级补条只能另立文档批。 +**现状**:用户 2026-10-19 会话裁定的 ECS 架构依据(系统无状态——效果引擎这类系统零运行时可变状态、数据由宿主对象持有并随宿主生灭、状态按参数传入系统、系统只做判定)是「效果引擎无状态化」重构批的立项判据(上游条目=本清单「计数器寿命域未统一」,提案=design/research/提案-效果引擎无状态化-2026-10-19.md v1.3 §7.9 #1),但 `design/engineering/architecture/architecture.md`「架构原则」节(原 7 条)无「系统无状态」条目——立项判据暂无权威文档出处(2026-10-19 全仓检索「无状态/纯计算」零命中,提案 §10.3 实查;原 `design/registry/` 两 yaml 已随 2026-10-19 用户裁注销删除,无可迁凭据)。重构批是代码批、禁写 `design/`,文档级补条只能另立文档批。 -**缺口**:一次文档设计讨论——「系统无状态」原则的条文表述(与现行 7 条架构原则的交叉与序位:核心层纯逻辑/fail-fast 两原则与之相邻但不等同)+写入 architecture.md 的批次编排。 +**现状换代(2026-10-21 文档批写入完成)**:architecture.md「架构原则」节已补第 8 条「系统无状态」(条文序位=呈现层契约成文条之后,与条 1 核心层纯逻辑、条 5 fail-fast 交叉核过无冲突),effect_engine 模块行与战斗域装配节同步改写为 ctx 形态描述——design/engineering/architecture/architecture.md v1.9(2026-10-21 用户裁写入)。 **归属**:design/engineering/architecture/architecture.md(架构原则节) -**状态**:待文档设计 +**状态**:文档设计已闭合 --- @@ -720,3 +722,57 @@ **归属**:`game/presentation/` 与 `game/data/tables/settlement.tres`(走独立 worktree 批;⑤ 连带渲染基线) **状态**:待写卡 + +--- + +#### 迭代 32 卡① 反哺点写入(2026-10-21 登记,来源=批次移交,设计面=反哺点) + +**现状**:清单=reports/iter32-卡①反哺点-2026-10-20.md(16 项);关联文档: +- 术语表:design/gdd/术语表.md(「退役词对照」新增「完美排雷→完美封印」行,2026-10-21 写入) +- 措辞换代八件:design/gdd/systems/战斗循环/战斗结算.md、地图战斗资源.md、战斗表现.md、design/gdd/systems/表现与支撑/HUD框架.md、design/gdd/systems/冒险循环/难度曲线与Boss.md、design/gdd/ux/battle.md、design/gdd/ux/interaction-patterns.md、design/art/art-bible.md(v3.17) +- 文档域禁词闸:tools/doc_term_audit.py(词表加「完美排雷」+扫描域扩 design/art,2026-10-21 用户裁;变异验证=注入见红、还原回绿) +- 目检入册:体验验证清单.md ㉚ 节(2026-10-21) +- 代拍板追认:reports/iter32-卡①代拍板-2026-10-20.md 七条,2026-10-21 用户全部追认 +- 遗留去向:#11 门票三处随「2026-10-18 冒记案遗留待裁两项」②另批(用户裁);#12 巢穴换代与单字「旗」清理待用户裁后另立批;#13 A 表词不纳 S11 词表(用户裁维持现状);#15 重锚见本清单「结算明细日志行序重锚批」条目;#16 状态推进已执行(见「代码注释禁用词清扫批」条目) + +**归属**:design/gdd/ 八件+design/art/art-bible.md+tools/doc_term_audit.py(文档域) + +**状态**:已写入 + +--- + +#### 迭代 32 卡② 反哺点写入(2026-10-21 登记,来源=批次移交,设计面=反哺点) + +**现状**:清单=reports/iter32-卡②反哺点-2026-10-20.md(13 项);关联文档: +- 架构三处:design/engineering/architecture/architecture.md v1.9(effect_engine 行与 battle_orchestrator 行改 ctx 形态、战斗域装配节去 export/seed 语义、架构原则补第 8 条「系统无状态」;同批订正旧事件名 flag_missed→seal_missed 两处) +- 立项条闭合:本清单「效果引擎系统无状态原则缺架构文档条目」状态已推进(v1.9 凭据在册) +- 寿命域条目:本清单「计数器寿命域未统一」整条删除归收尾批执行(其证据面缺口=V1 变异红已闭,见实现报告 §9 补漏记录) +- 提案订正三处:design/research/提案-效果引擎无状态化-2026-10-19.md v1.3(§7.7 零采集改批内重采、§7.10.3 前缀判据采松版、§7.10.12 字段面 33+三组判读,依卡片 §12 裁①②) +- 目检入册:体验验证清单.md ㉚ 节(V14 锋/守限次观感) +- 代拍板追认:reports/iter32-卡②代拍板-2026-10-20.md 七条,2026-10-21 用户全部追认 +- 偏差注记:#12 S 编号以 S12=旧件零残留为准、#13 V12 基线哈希以重采值为准(均随卡片与实现报告退役消亡) +- 采集纪律例外:sim-data/README.md 配套纪律③⑦批次例外登记(2026-10-21 写入;现行锚与读数文件未动) + +**归属**:design/engineering/architecture/+design/research/提案+sim-data/README.md+本清单(文档域) + +**状态**:已写入 + +--- + +#### 结算明细日志行序重锚批(2026-10-21 登记,来源=批次移交,设计面=反哺点) + +**现状**:迭代 32 卡① N7 改动互换 `seal_miss`/`insurance_used` 两行日志顺序并改写豁免态 highlight(依据与预期漂移两例见 reports/iter32-卡①实现报告-2026-10-20.md「已记档差异」节);与基线数据逐项比对的 JSONL sha256 校验必红,实现批按规未发起、11 号闸落 skip。**用户 2026-10-21 裁=批准另立重锚批,发起时点另定**(重锚批只能由用户发起)。 + +**归属**:`sim-data/` 锚与 `tools/parity_anchor.py`(重锚执行归用户发令批) + +**状态**:待裁决 + +--- + +#### `game/` 域文档两处措辞订正欠账(2026-10-21 登记,来源=批次移交,设计面=工程直入) + +**现状**:两处 `game/` 内文本与现实不符,改 `game/` 任何路径都会触发代码域全量测试(2026-10-20 用户裁「零代码批不改该行、登记欠账」),故不入本写入批:①`game/tests/static_scan.sh:100` S11 注释仍称「完美排雷」不在退役词对照表里——2026-10-21 起该词已入表(术语表退役词对照行在册),注释与 `:122` 追加行按「S11 权威=术语表解析」口径可一并订正;②`game/tests/README.md:58` 记「manifest 已登记实跑 26 套件」——迭代 32 卡② 后现况为 35 套件(含 counter_prefix_fatal 负面套件),以 `run_all.gd` 现况为准更新。 + +**归属**:`game/tests/`(代码域,随下一个触碰 game/ 的批次顺带清) + +**状态**:待写卡 From 68f7f77d8dc7eecdf1d990857b22c65dbd423b8d Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 04:16:10 +0800 Subject: [PATCH 49/59] =?UTF-8?q?docs(=E5=BE=85=E5=8A=9E):=20=E9=AA=8C?= =?UTF-8?q?=E6=94=B6=E9=97=AD=E5=90=88=E8=A7=82=E5=AF=9F=E9=A1=B9=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E9=A1=BA=E5=B8=A6=E8=A7=82=E5=AF=9F=E2=80=94=E2=80=94?= =?UTF-8?q?=E6=97=A0=E7=BC=BA=E6=BC=8F=E6=97=A0=E8=AF=AF=E7=BA=A2=E5=8D=B3?= =?UTF-8?q?=E8=A7=86=E4=BD=9C=E9=80=9A=E8=BF=87=EF=BC=8C=E6=94=B6=E5=B0=BE?= =?UTF-8?q?=E6=95=B4=E6=9D=A1=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 本条目不是必做任务(用户 2026-10-21 裁定):规则评估按观察口径执行, 下一次迭代没有暴露验收缺漏或误红就自动作废,只有实测发现问题才转成修订任务。 --- 待办清单.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/待办清单.md b/待办清单.md index 3a363594..304a2e91 100644 --- a/待办清单.md +++ b/待办清单.md @@ -6,7 +6,7 @@ **现状**:2026-10-21 已改工作流技能与规约——[测试规范](design/engineering/test-conventions.md) 新增 §9(改动—验收对照表、真实入口、撤销证明、禁削弱、独立验收审计),[AGENTS.md](AGENTS.md) 硬性红线新增「验收闭合」,`req-card`/`iter`/`batch-closure` 三份技能同步,[流水线闸](tools/pipeline_gate.py) 新增 C3 卡片结构检查。规则文本已落地,还没在真实迭代上跑过。 -**归属**:下一次迭代的实现批(按新规写卡、施工、审计;实测规则是否抓到缺漏、是否误红)。 +**归属**:下一次迭代的实现批(按新规写卡、施工、审计)。本条目不是必做任务,是顺带观察项:该迭代跑完若没有出现验收缺漏、也没有误红,规则即视作通过,收尾时整条删除;只有实测发现缺漏或误红,才转成修订任务。 **状态**:待裁决 From cd72943032c747a6ad7fbcfd86abede71cb31aa8 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 04:19:06 +0800 Subject: [PATCH 50/59] =?UTF-8?q?docs(=E8=BF=AD=E4=BB=A332=E6=94=B6?= =?UTF-8?q?=E5=B0=BE=E6=89=B9):=20=E6=89=B9=E5=90=8E=E6=94=B6=E5=B0=BE?= =?UTF-8?q?=E4=B8=8E=E4=B8=AD=E9=97=B4=E6=96=87=E6=A1=A3=E9=80=80=E5=BD=B9?= =?UTF-8?q?=E2=80=94=E2=80=94=E5=85=AB=E4=BB=B6=E4=BA=A7=E5=87=BA=E7=89=A9?= =?UTF-8?q?=E9=80=80=E5=BD=B9=EF=BC=8B=E8=B4=A6=E9=9D=A2=E6=8D=A2=E4=BB=A3?= =?UTF-8?q?=EF=BC=8C=E6=96=87=E6=A1=A3=E5=9F=9F=E9=97=B8=E5=85=A8=E7=BB=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - reports/ 退役六件 iter32 产出物(实现报告/代拍板追认单/反哺点清单×2卡)+两张需求卡片(判据全过:29 项反哺已写入、代拍板 14 条用户全追认、遗留读数义务已迁体验验证清单 ㉚/待办清单重锚条目) - 待办清单整条删除四处:计数器寿命域未统一/代码注释禁用词清扫批(完成即删)/卡①卡②反哺专条(已写入即删);重锚条目指针改结论内联+git 提交号 - 提案死链改写(卡片指路句换 git 提交号 f2bb5871);roadmap 迭代 32 行「已完成(2026-10-21)」+卡片与报告列填退役保留字;当前位三行换代(下一动作=编排迭代 33) 〔迭代 32 收口登记:卡① 880ee91b/卡② d00f24a8/反哺写入 fc1e8027〕 --- .../提案-效果引擎无状态化-2026-10-19.md | 2 +- reports/iter32-卡①代拍板-2026-10-20.md | 17 - reports/iter32-卡①反哺点-2026-10-20.md | 44 -- reports/iter32-卡①实现报告-2026-10-20.md | 77 ---- reports/iter32-卡②代拍板-2026-10-20.md | 17 - reports/iter32-卡②反哺点-2026-10-20.md | 51 --- reports/iter32-卡②实现报告-2026-10-20.md | 99 ---- ...œ€求卡片-代码注释禁用词清扫批-2026-10-20.md | 432 ------------------ .../需求卡片-效果引擎无状态化批-2026-10-20.md | 339 -------------- roadmap.md | 6 +- 待办清单.md | 68 +-- 11 files changed, 5 insertions(+), 1147 deletions(-) delete mode 100644 reports/iter32-卡①代拍板-2026-10-20.md delete mode 100644 reports/iter32-卡①反哺点-2026-10-20.md delete mode 100644 reports/iter32-卡①实现报告-2026-10-20.md delete mode 100644 reports/iter32-卡②代拍板-2026-10-20.md delete mode 100644 reports/iter32-卡②反哺点-2026-10-20.md delete mode 100644 reports/iter32-卡②实现报告-2026-10-20.md delete mode 100644 reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md delete mode 100644 reports/需求卡片-效果引擎无状态化批-2026-10-20.md diff --git a/design/research/提案-效果引擎无状态化-2026-10-19.md b/design/research/提案-效果引擎无状态化-2026-10-19.md index 494fc31e..16a93f2f 100644 --- a/design/research/提案-效果引擎无状态化-2026-10-19.md +++ b/design/research/提案-效果引擎无状态化-2026-10-19.md @@ -555,7 +555,7 @@ func counters_merge_export(exported): ### 10.1 行号订正汇总 -> 🔴 **2026-10-20 再漂移注记**:本表「实际」列的行号以提案复核时点为准;其后的 `c5200b6b`(禁写变更记录批·代码注释清偿)已使本文件部分行号再度漂移(如引擎成员块现役 :83-88、`counters_seed` :255、`EffectEngine.new` :271、树合成行 :136-155)。行号时效以需求卡片 `reports/需求卡片-效果引擎无状态化批-2026-10-20.md`(开工前实查)为准,本节数字仅作沿革参考。 +> 🔴 **2026-10-20 再漂移注记**:本表「实际」列的行号以提案复核时点为准;其后的 `c5200b6b`(禁写变更记录批·代码注释清偿)已使本文件部分行号再度漂移(如引擎成员块现役 :83-88、`counters_seed` :255、`EffectEngine.new` :271、树合成行 :136-155)。行号时效以开工前代码实查为准(对应需求卡片已随迭代 32 退役,全文见 git 提交 f2bb5871),本节数字仅作沿革参考。 | 草案初版写法 | 实际 | 说明 | |---|---|---| diff --git a/reports/iter32-卡①代拍板-2026-10-20.md b/reports/iter32-卡①代拍板-2026-10-20.md deleted file mode 100644 index e350fbcf..00000000 --- a/reports/iter32-卡①代拍板-2026-10-20.md +++ /dev/null @@ -1,17 +0,0 @@ -# 迭代 32 卡① 代拍板追认单(2026-10-20) - -批次内落入卡片 §9 代拍板白名单的微决策,逐条备案确认(授权发生于卡片审问阶段,实现只执行预授权)。 - -| # | 决策 | 白名单条目 | 落点 | -|---|---|---|---| -| 1 | 注释换代措辞等价微调:`static_scan.sh:73`「数值单一事实源的正主」→「数值单一事实源自身」(等价表述,非硬套「现行事实源」致句意断裂) | §9.1 | static_scan.sh:73 | -| 2 | `落籍`→`已入库` 在带 commit 号(9cc4b8b)的历史注记行不改,保留「已落籍」 | §9.2 | enemy.tres:653 | -| 3 | `正主` 误报处「正主角池」(正主+角池)不改 | §9.3 | damage_math_test.gd:36 | -| 4 | 测试断言描述文本替换措辞取语义等价 | §9.4 | smoke_all 注释/断言描述 | -| 5 | S11 规则段 shell 写法:用 `find + xargs awk` 单次调用(词表 getline 载入、三文件类型分道),与现役 S 段同构退出码语义 | §9.5 | static_scan.sh S11 段 | -| 6 | N7 两态文案末字:已破态「清图奖励不再加倍」、豁免态「不计入完美封印判定」,因果不变成立 | §9.6 | battle_log_view.gd:192 | -| 7 | battle_log_view 局部变量改名 `suffix`→`miss_note` 避开外层同名遮蔽(实现细节,非语义) | §9.5 延伸 | battle_log_view.gd | - -**超白名单呈报(已停机自查消解,非代裁)**: -- 卡片 §2 豁免单预测的 `level_runner.gd:832`、`adventure_runner.gd:403` 两处,开工复核发现现行代码该行已无对应退役词(卡片成文后代码前进)。据「开工自行复核」条款按现实处理:无需豁免(词已不在该位),S11 注释面为权威判据。不新增豁免、不改代码凑绿。 -- 全局 sed 曾误改移交三处(display_name/玩家文案)与 static_scan.sh 词表追加行,已逐处精确还原并补 S11 自指豁免,属施工返工非代拍板。 diff --git a/reports/iter32-卡①反哺点-2026-10-20.md b/reports/iter32-卡①反哺点-2026-10-20.md deleted file mode 100644 index 8bf5ad2c..00000000 --- a/reports/iter32-卡①反哺点-2026-10-20.md +++ /dev/null @@ -1,44 +0,0 @@ -# 迭代 32 卡① 反哺点清单(2026-10-20) - -本批为代码实现批,禁写 `design/` 整目录与根规则文件。发现要改文档的点逐条列此,用户在会话裁决后归文档批落文(`design/` 对本批只读)。落点对应卡片 §5 关联文档同步面。 - -## GDD 文档面(「完美排雷」→「完美封印」措辞同步) - -| # | 文档 | 关联点 | 建议改成 | 依据 | -|---|---|---|---|---| -| 1 | `design/gdd/术语表.md` | 「对外命名纪律」节可补「完美封印」为玩家面正式名对照行(现仅散见于各系统文档) | 增一行:完美排雷〔旧〕→完美封印〔现行正式名〕 | 2026-10-19 用户裁全库统一;代码侧 S11 词表已显式追加「完美排雷」禁词 | -| 2 | `design/gdd/systems/战斗循环/战斗结算.md`(:85/:108/:116/:139/:141/:161/:259/:342) | 全篇仍称「完美排雷」,与 `奇物.md` v3.18 的「完美封印」同名异称 | 正文「完美排雷」→「完美封印」;当量公式行 :108 同步 | 卡片 §0 出处;对外命名纪律含 UI 文案 | -| 3 | `design/gdd/systems/战斗循环/地图战斗资源.md`(:155/:194) | 兑付结构段称「完美排雷」 | →「完美封印」 | 同上 | -| 4 | `design/gdd/systems/战斗循环/战斗表现.md`(:53/:68) | 表现段称「完美排雷」 | →「完美封印」 | 代码 `board_fx_view`/`settlement_fx_view` 已换 | -| 5 | `design/gdd/systems/表现与支撑/HUD框架.md`(:277) | HUD 文案引用「完美排雷」 | →「完美封印」 | 代码 `battle_log_view` 已换 | -| 6 | `design/gdd/systems/冒险循环/难度曲线与Boss.md`(:224/:227/:313) | 「完美排雷」措辞 | →「完美封印」 | 同名异称统一 | -| 7 | `design/gdd/ux/battle.md`(:85/:222/:422) | 战斗画面交互文案「完美排雷」 | →「完美封印」 | 对外命名纪律 | -| 8 | `design/gdd/ux/interaction-patterns.md`(:90) | 「完美排雷」 | →「完美封印」 | 同上 | -| 9 | `design/art/art-bible.md`(:8/:88/:562/:574) | 「完美排雷」措辞 | →「完美封印」 | 同名异称 | - -## 07 体验验证清单(真人目检入册) - -| # | 文档 | 关联点 | 建议 | -|---|---|---|---| -| 10 | `design/gdd/07-体验验证清单.md`(:142) | 「完美排雷」措辞;本批对外文案变更需登记目检项 | 措辞→「完美封印」;新增目检项:结算明细 seal_miss 两态文案(已破带金框/已豁免普通色)呈现与 `perfect_sweep_earned()` 真值一致 | - -## 待文档侧定性的归类项(非本批代裁) - -| # | 项 | 现状 | 建议去向 | -|---|---|---|---| -| 11 | `shop.tres:86`「奇物门票」display_name + `curio_interact_controller.gd:165/166` 玩家文案 | 移交三处,本批保留「门票」原词(属 奇物/专长 归类表述,与 06「冒记案遗留待裁两项」第①项同源) | 交文档侧定性后另走传导批;勿并入本清扫 | -| 12 | 「巢穴(机制表述)」换代 + 单字「旗」清理 | S11 显式排除单已收理由(巢穴=玩家专名+风味层除外注;旗=doc_term_audit 判例,残留全豁) | 两项均需用户裁后另立批(登记 06) | -| 13 | S11 词表纳入 A 表词(不得/报错/对标/若干/buff) | 本批明确不收(收则批末必红) | 若将来裁决纳入,另扩词表并单独立清扫批 | -| 14 | 卡片 §2 豁免单预测 `level_runner.gd:832`、`adventure_runner.gd:403` | 开工复核:现行代码该行已无对应退役词(卡片成文后代码前进) | 反哺点记录卡片与现实偏差;卡片如需订正归文档批 | - -## parity 重锚批(登记 06) - -| # | 项 | 建议 | -|---|---|---| -| 15 | N7 改动致 `seal_miss`/`insurance_used` 行序与 highlight 漂移(契约 12) | 合回后另立**用户批准**的 parity 重锚批并登记 06;预期漂移两例见实现报告「已记档差异」节 | - -## 06 待办清单 - -| # | 项 | 建议 | -|---|---|---| -| 16 | 本批条目「代码注释禁用词清扫」状态推进 | 卡①合回后由文档批推进至「实现已闭合」;本批不写 06 | diff --git a/reports/iter32-卡①实现报告-2026-10-20.md b/reports/iter32-卡①实现报告-2026-10-20.md deleted file mode 100644 index 2dc48afc..00000000 --- a/reports/iter32-卡①实现报告-2026-10-20.md +++ /dev/null @@ -1,77 +0,0 @@ -# 迭代 32 卡① 实现报告·代码注释禁用词清扫批(2026-10-20) - -- **批次**:迭代 32 执行序①(代码注释禁用词清扫批) -- **分支**:`g-plan2-iter32-card1-comment-sweep` -- **合回前 tip**:`b3b77ff1` -- **闸回执**:`game/tests/.gates/receipt.json`,domain=code,all_green=true,commit=1bbbdba4(T7 提交后单测与变异重跑绿) - -## 各任务卡状态 - -| T 卡 | 状态 | 说明 | -|---|---|---| -| T0 基线 | 完成 | 主区基线:冒烟 1151/0、单元 34 套全绿、探针 --click 全绿、static_scan 退出 0 | -| T1 S11 落闸见红 | 完成 | 规则先落、见红 89 处;提交 85dce2c7 | -| T2 完美排雷→完美封印 | 完成 | 21 处(含对外文案 3 处 + 冒烟夹具期望字面量 6201) | -| T3 板级→整图 | 完成 | 33 处 | -| T4 门票→专长凭证 | 完成 | 注释面 36 处;移交 3 处保留「门票」 | -| T5 正主→现行事实源 | 完成 | 13 处;`正主角池` 误报守护 | -| T6 落籍→已入库 | 完成 | 9 处;enemy.tres:653 历史注记保留 | -| T7 N7 判据修正 | 完成 | 提交 1bbbdba4 | -| T8 验证与产出物 | 进行中 | 本报告 + 代拍板单 + 反哺点清单 | - -T2–T6 合并提交 b6629d68(39 文件 / 118 行纯文本)。 - -## 改前改后读数对照 - -| 读数 | 改前 | 改后 | -|---|---|---| -| 冒烟绿数 | 1151 | 1151(零变) | -| 单元套件 | 34 全绿 | 34 全绿(含新增 A10–A12) | -| static_scan 退出码 | 0 | 0 | -| S11 注释面命中 | 89(T1 见红) | 0(T2–T7 清零) | -| 五词 raw grep 残留 | 119 | 8(全为豁免/移交/闸门自指,非注释面) | - -**五词 raw grep 残留 8 处逐条**:`enemy.tres:653`(落籍·豁免·历史注记)、`shop.tres:86`(门票·移交 display_name)、`curio_interact_controller.gd:165/166`(门票·移交玩家文案)、`static_scan.sh:97/100/122`(完美排雷·S11 闸门自指)、`damage_math_test.gd:36`(正主角池·误报豁免)。 -注:卡片 §2 豁免单预测的 `level_runner.gd:832`、`adventure_runner.gd:403` 经开工复核,现行代码该行已无对应退役词(卡片成文后代码前进),故不出现;S11 注释面口径为权威判据,现绿。 - -## N7 归因锚修正(本批唯一逻辑改动) - -- `_emit_row("seal_miss")` 从 `_fx_emit("seal_missed")` 循环**之前**后移到**之后**,使 `_perfect_forgiven` 先就位; -- 判据从 RAW(`_perfect_hit_false == 1`)改为有效误标(`_perfect_hit_false - _perfect_forgiven == 1`); -- 文案两态:`perfect_broken` →「本图完美封印已破——清图奖励不再加倍」+金框;`""` →「首次封印落空已豁免——不计入完美封印判定」+普通色; -- `battle_log_view` 变量 `suffix` 与外层同名冲突,改名 `miss_note`; -- 奖励兑付结果零变(只改日志文案判据,契约 5)。 - -## 验收断言 A10–A12(落 feat_vouchers_test.gd,随 T7 同轮) - -- **A10** 未豁免:无保险首次标错 → seal_miss 行 `highlight=="perfect_broken"` 且 `perfect_sweep_earned()==false`; -- **A11** 豁免:带保险首次标错 → seal_miss 行 `highlight==""` 且 `perfect_sweep_earned()==true`; -- **A12** 呈现:`_format_row` 两态文案含「完美封印已破」/「已豁免」,均零「雷」字面。 - -## 变异验证记录表 - -| 变异点 | 注入形态 | 跑的闸 | 红输出 | 还原 | -|---|---|---|---|---| -| S11 拦截 | battle_orchestrator.gd:265 注释追加「板级」 | static_scan.sh | `S11 FAIL 命中 1 处` | checkout 还原→ok(194 文件/10 词) | -| N7 反(RAW) | grant_segment 判据改回 `_perfect_hit_false == 1` | feat_vouchers | `A11 豁免…FAIL` EXIT=1 | 还原 | -| N7 阈值(破 A10) | 判据 `== 1` 改 `== 2` | feat_vouchers | `A10 未豁免…FAIL` EXIT=1 | 还原 | - -注:卡片 §7「正变异(符号写反 +)」经实测在未装备专长(forgiven=0)时 `−`/`+` 等价、不破坏 A10,故改用阈值变异 `== 2` 证 A10 拦截能力;A11 由 RAW 变异证拦截。A12 为文案常量比对,随 A10/A11 判据承载,无独立变异。 - -## 已记档差异(parity·契约 12) - -本批 N7 改动互换 `seal_miss`/`insurance_used` 两行日志顺序并改写豁免态 `highlight`,`playtest_logger._on_step_row` 逐行落盘含 `highlight` 字段,11 号闸 JSONL sha256 逐位比对必红。**本批不发起 parity**(回执 11 号落 skip、入 not_run,all_green 不受影响)。 - -预期漂移两例(供合回后用户批准重锚批对照): -1. **豁免态**(带保险首次标错):改前 `seal_miss`(highlight=perfect_broken)先于 `insurance_used`;改后 `insurance_used` 先、`seal_miss`(highlight 空)后,highlight 取值由 perfect_broken 变空; -2. **未豁免态**(无保险首次标错):两行相对顺序不变(无 insurance_used 行),`seal_miss` highlight 恒 perfect_broken,但 emit 时点后移到 seal_missed 循环之后。 - -## 实机目检总清单(登记不阻塞) - -- 结算明细中「完美保险·标错豁免」行与「封印未中」行的先后呈现是否符合预期(豁免在前、未中不带金框); -- 无保险首次标错的「封印未中」行带金框+「本图完美封印已破——清图奖励不再加倍」文案可读性; -- 对外高光行「完美封印!清图奖励 ×2」与 banner「完美封印 ×2」显示正确。 - -## 遗留读数义务 - -- 合回后另立**用户批准**的 parity 重锚批(登记 06),本批不借任何批顺手重锚。 diff --git a/reports/iter32-卡②代拍板-2026-10-20.md b/reports/iter32-卡②代拍板-2026-10-20.md deleted file mode 100644 index cdde7d3b..00000000 --- a/reports/iter32-卡②代拍板-2026-10-20.md +++ /dev/null @@ -1,17 +0,0 @@ -# 迭代 32 卡② 代拍板追认单(2026-10-20) - -批次内落入卡片 §11 代拍板白名单的微决策,逐条备案确认(授权发生于卡片审问阶段,实现只执行预授权)。 - -| # | 决策 | 白名单条目 | 落点 | -|---|---|---|---| -| 1 | 负面套件命名/夹具诊断文案("违规表被放行""校验通道静默化""正确拒绝")措辞,退出码协议 1/2 已锁 | §11.6 | counter_prefix_fatal_test.gd | -| 2 | 引用闭合声明集口径:采「任一 do.counter_id 行」而非「仅 kind=counter_add」——因 insurance_used 经 `forgive_seal_miss` 行的 do.counter_id 由 _apply_counter_hit 写入,严版会误判其为悬空 | §11.3 延伸(判据语义微调,成员判定本体不变) | config_db_cross_validator.gd ⑦ | -| 3 | S12 段 shell 写法:`find | xargs -0 grep -lEn` 命中文件数 + 非空自检,与现役 S 段同构 | §11.7 | static_scan.sh S12 | -| 4 | 冒烟裸引擎段 ctx 取用:rig 段取 `orch.counters_ctx`(真实挂载路径),_smoke_tree_rules standalone 引擎自建 `EffectContext.new()`(sense 用共享 level 字典引用复刻跨战持久) | §11.2 | smoke_all.gd | -| 5 | effect_words_t1 ⑥⑦重写措辞(adventure 桶共享字典往返/round_ 前缀整桶清空 vs battle 无前缀存活),断言语义承卡片 §4.1 D1/E1 | §11.1 | effect_words_t1_test.gd | -| 6 | parity 复放文件名与判读排版(off/formed/rules 三组、--mode 两判据、字段集从基线推导)内部实现自由 | §11.7/§11.8 | parity_compare.py | -| 7 | V16 既有断言写键 twin_digs→adv_twin_digs、V13 旧键用字符串拼接构造(避 S12 旧件扫描字面,语义不变) | §11.1 延伸 | feat_vouchers_test.gd | - -**超白名单呈报(消解,非代裁)**: -- **S 编号冲突**:卡片 §7 写「static_scan.sh 新增 S11 段」,但卡①(执行序①,先合入 master)已占用 S11(代码注释禁用词)。本批旧件扫描落 **S12**(顺延取下一号),判据与扫描面严格按卡片 §7 F1/V10 实现。此属卡片成文时 S11 未定义的现实偏差,归反哺点,未改卡片、未凑绿。 -- **V12 基线重采**:卡片 T0 记录预采基线 game 树哈希 f75acc15;卡① 改 game/ 后树前进到 4b34a656,据卡片 T0「若不等则留盘基线作废、按 T7 命令重采」条款重采三组 40 局;重采基线哈希 2d3d4247/0fcbcb26 逐字复现卡片在册值,证明重采口径与卡片一致。 diff --git a/reports/iter32-卡②反哺点-2026-10-20.md b/reports/iter32-卡②反哺点-2026-10-20.md deleted file mode 100644 index b8ca51a7..00000000 --- a/reports/iter32-卡②反哺点-2026-10-20.md +++ /dev/null @@ -1,51 +0,0 @@ -# 迭代 32 卡② 反哺点清单(2026-10-20) - -代码实现批,禁写 `design/` 与根规则文件。要改文档的点逐条列此,用户裁决后归文档批落文。对应卡片 §6 关联文档同步面。 - -## architecture.md(三处) - -| # | 位置 | 现陈述 | 建议改成 | 依据 | -|---|---|---|---|---| -| 1 | 模块归属表 effect_engine 行「对外暴露」列(:116) | 记 `counters_export·counters_seed` 与「domain=adventure 跨战斗持久」 | 改写为 ctx 形态:`dispatch(ctx,...)`/静态 `counter_add·counter_spend·bucket_of`;跨战持久=经 EffectContext 引用宿主持有桶(无 export/seed) | 搬运链已整段删除,该陈述失义 | -| 2 | 战斗域装配现状节(:125) | 「战末 export/开局 seed 时点语义不变」 | 删除或改「adventure 桶经 ctx 引用直写 RunLedger,无搬运时点」 | 同上 | -| 3 | 「架构原则」节 | 缺「系统无状态」条目 | 补一条(立项判据)——**指向 06 在册条目「效果引擎系统无状态原则缺架构文档条目」**,由文档批执行补条 | 卡片 §6 + 提案 §7.9#1/§7.10.16 B1 | - -## tests/README.md - -| # | 现陈述 | 建议改成 | -|---|---|---| -| 4 | :58「manifest 已登记实跑 26 套件」(卡片所载) | 本批实跑单元 35 套件(+1 counter_prefix_fatal 负面套件);套件数与段描述由文档批更新到现实数(注意卡①/卡②并行期计数漂移,以 run_all.gd 现况为准) | - -## 06-待办清单 - -| # | 项 | 建议 | -|---|---|---| -| 5 | 上游条目「计数器寿命域未统一」 | 随本批完成整条删除(收口=batch-closure 技能);其现状内引用的行号(adventure_runner :838-841 等)随实现漂移,删除时一并消亡 | -| 6 | 新增条目「效果引擎系统无状态原则缺架构文档条目」 | 本批实现落地后,该文档轨条目待文档批补 architecture.md 原则条;06 状态推进与条目清掉归文档批 | - -## 07-体验验证清单 - -| # | 项 | 建议 | -|---|---|---| -| 7 | 天赋树锋/守「每关第 3 次起无减半/无返 AP」=玩家可感知削弱 | 登记目检项(实现报告实机目检总清单已列 V14),用户实战验;只登记不阻塞 | - -## design/research/提案-效果引擎无状态化(三处口径订正——依卡片 §12 裁决以卡片为准) - -| # | 提案节 | 卡片裁定 | 建议 | -|---|---|---|---| -| 8 | §7.10.3 前缀判据「meta_ 及其余未知前缀→违例」 | 14 枚 id 全含下划线,严版误伤全部既有 battle id;封闭前缀词表=第二事实源 | 采「只禁 meta_+其余落 battle」松版+引用闭合承接(提案随文档批订正) | -| 9 | §7.10.12 复放判读「27 字段+levels_cleared 不得上行」 | 实采 33 字段;单一不得上行判据把增强组与削弱组混判 | 采三组分类判据(off 逐位/formed·rules 输入面恒等,方向只记报告)——本批已按此实现 | -| 10 | §7.7「零采集」定值 | 现行锚 24 字段与本批不同构,不可作复放基线 | 改批内重采三组 40 局(已做);提案随文档批订正 | - -## sim-data/README.md - -| # | 项 | 建议 | -|---|---|---| -| 11 | 配套纪律③「对拍=0 新跑」⑦「零数值改动=零 MC」 | 登记本批批次例外:V12 三组 40 局基线重采+40 局复放(二档上限内,依卡片 §12 裁点①);现行锚与读数文件未动 | - -## 卡片与现实偏差(本批实况,非代裁) - -| # | 项 | 说明 | -|---|---|---| -| 12 | static_scan 编号 | 卡片写「S11 段」,卡① 已占 S11;本批旧件扫描落 S12(顺延)。卡片如订正归文档批,或后续以「S12=旧件零残留」为准 | -| 13 | V12 基线哈希 | 卡片 T0 记 f75acc15 基线;卡① 改 game/ 致树前进 4b34a656,据 T0 条款重采,新基线复现卡片 formed/rules 在册哈希 2d3d4247/0fcbcb26 | diff --git a/reports/iter32-卡②实现报告-2026-10-20.md b/reports/iter32-卡②实现报告-2026-10-20.md deleted file mode 100644 index a505a923..00000000 --- a/reports/iter32-卡②实现报告-2026-10-20.md +++ /dev/null @@ -1,99 +0,0 @@ -# 迭代 32 卡② 实现报告·效果引擎无状态化批(2026-10-20) - -- **批次**:迭代 32 执行序②(效果引擎无状态化批·架构重构 restructure) -- **分支**:`g-plan2-iter32-card2-stateless`(基点 master 880ee91b=卡① 合回点) -- **设计事实源**:`design/research/提案-效果引擎无状态化-2026-10-19.md` v1.2 -- **合回前 tip**:b42463c9(+ 本报告等产出物提交后为最终 tip) -- **闸回执**:`game/tests/.gates/receipt.json` domain=code,all_green=true,11 号 parity 落 skip - -## 完成定义 8 条逐项核对 - -| # | 完成定义 | 状态 | 证据 | -|---|---|---|---| -| 1 | EffectEngine 实例零运行时可变数据 | ✅ | 仅剩 `_triggers`(编译产物)+`db`(只读);`_counters/_reset_on_round_start/_adventure_counter_ids` 删除(T2 a721e52) | -| 2 | 四桶外置、宿主持有、随宿主生灭 | ✅ | round/battle→BattleOrchestrator、level→LevelRunner.level_counters、adventure→run_ledger.adventure_counters(T1 ae5baed) | -| 3 | 搬运链整段删除零残留 | ✅ | counters_export/counters_seed/counters_merge_export/counters_seed_snapshot 删除;S12 静态扫描 game/**/*.gd+*.tres 零命中(T7 003581f) | -| 4 | 硬编码清除名单删除、按关清零改由 level 桶 new 承载 | ✅ | _reset_tree_limited_counters 删除(T1) | -| 5 | 前缀归属机器可读+加载期可校验+引用闭合 | ✅ | validate_trigger_row 前缀致命 + _push_trigger assert + config_db ⑦ 引用闭合;负面套件两断言(meta_ 非法/悬空读点)正确拒绝(T5 4c5bdbc) | -| 6 | V12 批内同种子复放三组判读通过 | ✅ | off 组 base==post 逐字节一致(bf084ef3…);formed/rules input-parity PASS(详见 V12 节) | -| 7 | dig_combo 死读数连同 combo 分支删除、零行为差 | ✅ | T3 删除;S12 含 dig_combo 相关旧件零残留;off 组逐位一致佐证零行为差 | -| 8 | 旧档断点含改名前旧键加载不崩(无迁移) | ✅ | V13/H1 断言(430f97f):注入 tree_sense_*/twin_digs 旧键 resume 受理零崩溃、留桶成死键 | - -## 改前改后读数对照 - -| 读数 | 改前(master 880ee91b) | 改后(卡② tip) | -|---|---|---| -| 冒烟绿数 | 1150 | 1150(旧 V10 直呼断言随函数退役 −1,本批裸引擎段迁移净变化归零) | -| 单元套件 | 34 全绿 | 35 全绿(+1=counter_prefix_fatal 负面套件) | -| static_scan 退出 | 0 | 0(新增 S12 绿) | -| 代码域闸 all_green | — | true | - -## T 卡状态 - -| T | 提交 | 状态 | -|---|---|---| -| T0 基线+采集器 rules 档类型修复 | a8db2257 | ✅ 首提交单列(无玩法改动);基线因卡① 改 game/ 树哈希漂移,据卡片 T0「重采」条款重采三组 40 局 | -| T1 EffectContext+四宿主接线 | ae5baed6 | ✅ | -| T2 引擎删状态+ctx 接口+静态写口 | a721e529 | ✅ | -| T3 7 施加点+dig_combo 删+run_ledger 搬运链删 | 96d31705 | ✅ | -| T4 round 泛化+宿主清零确认 | 并入 T2/T3 | ✅(round 整桶 clear+宿主 new 天然空) | -| T5 前缀双落点+引用闭合+负面套件+manifest | d402ea14, 4c5bdbc9 | ✅ | -| T6 数据行/合成行改名+domain/reset_at 删 | 7f45f904 | ✅ | -| T7 断言迁移+§9 正向断言+S12+V12+变异 | b226a292, 003581f4, a9d5ac13, b42463c9, 33e1f110 | ✅(§9 见下) | -| T8 产出物 | 本批 reports | ✅ | - -## §9 逐需求点正向验收主力(V1–V14·补漏记录 33e1f110) - -> 首合(d00f24a8)时本节缺 V1/V2/V6——只靠迁移旧测+V12 兜底。V12 formed/rules 输出面不作判据,adventure 桶跨战持久若坏不会红,核心缺陷消解无回归网。补漏批建齐并打〔无状态化 Vn〕尾缀: - -| V | 需求点 | 落点 | 断言 | 变异拦截 | -|---|---|---|---|---| -| V1 | adventure 桶跨战持久(真实事件面) | smoke `_smoke_counter_buckets` | 同一 RunLedger 两 begin_battle 各真实 request_dig→adv_twin_digs 经 ctx 累积=2、第2战读到持久值1 | **变异红**(桶引用改新建空字典→3 断言 FAIL) | -| V2 | adventure 桶新冒险置空 | feat_vouchers | start_adventure 后 run_ledger.adventure_counters 空 | — | -| V3 | adventure 桶随断点往返 | feat_vouchers V16 换代 | 写桶→快照→回读逐键一致 | — | -| V4 | level 桶同关跨战保持 | smoke `_smoke_tree_rules` | 共享 level 字典引用第2战读到限次值 | **变异红**(level 不共享→FAIL) | -| V5 | tree_sense 每关限 2 | smoke `_smoke_tree_rules` | 置 2 后 mine_hit 闸关零命中 | — | -| V6 | battle 桶随宿主销毁 | smoke `_smoke_counter_buckets` | 次战新编排器读 insurance_used=0 | — | -| V7 | 保险每战限次迁移保绿 | feat_vouchers V25 | 组内断言原样绿(双账不改面) | — | -| V8 | round 桶轮始清空 | effect_words_t1 ⑦ | round_ 前缀随 round_start 整桶 clear | — | -| V9 | 前缀致命+引用闭合 | counter_prefix_fatal_test | meta_/悬空读点两断言拒绝 | **变异红**(前缀分支置 false/闭合降 info→quit2) | -| V10 | 旧件零残留 | static_scan.sh S12 | game/**/*.gd+*.tres 旧符号 0 命中 | **变异红**(注入 counters_export→命中) | -| V11 | 旧断言同批摘除 | F2 迁移 | smoke 裸引擎段+4 单测件 ctx 化 | — | -| V12 | 同种子复放三组 | parity_compare.py | off 逐位/formed·rules 输入面恒等 | rules≠off 0 相同=非空转 | -| V13 | 旧档加载不崩 | feat_vouchers | 含改名前旧键 resume 受理零崩 | — | -| V14 | tree_sense 削弱目检 | 实机目检清单 | 每关第3次无减半/无返 AP | 用户实战验(只登记) | - - -## V12 同种子复放三组判读(完成定义 6 主力证据) - -基线码=master 880ee91b+采集器 rules 档类型修复(单独 worktree 采集);post 码=卡② tip。命令行逐字一致(normal/route=min/attune=off/shop=off)。 - -| 组 | 档 | 局数 | base sha | post sha | 判据 | 结论 | -|---|---|---|---|---|---|---| -| off | feat_mode=off | 20(81000–81019) | bf084ef3… | bf084ef3… | 整条逐位相等 | **PASS(字节级一致)** | -| formed | mode=formed | 10 | 2d3d4247… | 6e6423a5… | 输入面八字段+字段集恒等 | **PASS** | -| rules | rules+sense 两键 | 10 | 0fcbcb26… | f8af8da3… | 输入面八字段+字段集恒等 | **PASS** | - -- off 组 base==post 逐字节一致=未受影响路径(零 feats/零计数器触碰)确定性零漂移,结构迁移对其透明。 -- formed/rules 输入面(policy/seed/atk_pct/hp_pct/route/attune/equipped/feat_mode)恒等、种子集与局数一致、字段集恒等、零崩溃;输出面差异=已定性预期行为变更(adventure 桶真跨战持久、sense 每关限次、pain_layers 不跨战——契约 1 三处),**不声称零漂移**。 -- 判红先排除环境:基线哈希 2d3d4247/0fcbcb26 与卡片 T0 在册预采值逐字复现,证明基线采集口径正确。 -- **rules≠off 0 局相同**(分组非空转)——证采集器类型修复(T0 首提交)生效,rules 组确按 sense 两键注入。 - -## 变异验证记录表(test-conventions §6) - -| 断言 | 注入形态 | 跑的最窄闸 | 期望 | 结果 | -|---|---|---|---|---| -| V9(.tres 前缀侧) | validate_trigger_row 前缀分支置 `if false` | counter_prefix_fatal_test | ①非法前缀放行→quit2 | **EXIT=2 捕获** | -| V9(引用闭合侧) | 闭合 push_diag 严重级 error→info | counter_prefix_fatal_test | ②悬空读点放行→quit2 | **EXIT=2 捕获** | -| V10(S12) | reward_economy 注释写回 counters_export | static_scan.sh | S12 FAIL | **命中 1 文件见红**,还原回绿 | -| V12(采集器侧) | 去 Array 包裹(还原 T0 修复形态)→ 已在基线验证 | rules 组判读 | rules==off 即空转 | 实测 rules≠off 0 相同=非空转 | - -## 实机目检总清单(登记不阻塞·V14) - -- 天赋树锋/守:同一关内第 3 次起踩危险格不再伤害减半、第 3 次标错不再返 AP(每战限 2→每关限 2 的削弱,玩家可感知)——用户实战目检。 -- 断点续玩旧档(含改名前 counter 键)正常进入不崩(V13 自动化已覆盖崩溃面,此处目检手感)。 - -## 遗留读数义务 - -- 三处已定性行为变更由 V12 formed/rules 输入面判据+负面套件+冒烟桶断言承载;本批不声称零漂移。 -- V12 采集文件落 `sim-data/`(数据件不入 git,常驻留盘供报告与后续核对;本批不动现行锚)。 diff --git a/reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md b/reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md deleted file mode 100644 index 0795f2b9..00000000 --- a/reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md +++ /dev/null @@ -1,432 +0,0 @@ -# 需求卡片·代码注释禁用词清扫批(退役词换代+完美封印统一+归因锚判据修正) - -- **批次名**:代码注释禁用词清扫批 -- **日期**:2026-10-20 -- **批次性质**:工程债/重构 + 缺陷修复(两类均属工程直入四类,凭 06 在册条目与代码级证据直接写卡) -- **设计事实源**(唯一事实源:`design/gdd/术语表.md`「退役词对照」+「用语规范 A 表」+「对外命名纪律」节;`design/gdd/systems/战斗循环/战斗结算.md`「完美排雷」规则节;req-card 三选一之③工程直入证据指认):扫描读数=`game/` 下 195 个文件(.gd/.tres/.md/.json/.sh/.txt)逐处实测,落点带 file:line(见 §2);复现命令见 §2 末。 -- **版本**:**v1.3**(2026-10-20:二轮开工前自查(回应用户「是否还有需裁断项」)——五词全量审计 119 行命中,查出五处会卡住批末验收的问题全部钉死:①S11 词表若收「退役词对照」首列全词,巢穴 20 处(玩家专名+风味层)与旗 6 处(闸门自指+更名记载)批末必红 → 立显式排除单;②`enemy.tres:653` 落籍留档不被旧信号过滤豁免 → 批末 S11+A6 必红 → 废 25 子串信号过滤(实测误伤 14/17 处活注释),改显式留档豁免单 4 处;③误伤的 14 处活注释补入显式待清清单(N1 16→21、N2 26→33、N3 38→39、N4 12→13/14);④T7 行序调换+`hl` 两态化会漂移 parity JSONL(`_on_step_row` 逐行落盘含 `highlight`,11 号闸按 sha256 逐位比对)→ 立契约 11:本批不发起 parity、漂移记档、合回后另立用户批准的重锚批;⑤A2 补 `board_fx_view.gd:102` 静态覆盖(S11 只扫注释面,字符串字面量归断言面)。另订正 §10/§8 旧修法措辞(上移豁免→后移 `_emit_row`)与 N1 表内计数) -- 历史:v1.2(2026-10-20:开工前自检查出四处会卡住施工方的未定口径——S11 词表范围/「雷」字面误伤面/N7 修法可行性与限次重复消费/A10·A11 断言落点——全部钉死;T7 修法由「上移豁免」改为「后移 `_emit_row`」,已核实 `_fx_emit` 有状态不可重复调用) -- 历史:v1.1(2026-10-20:grilling 复核门查出 N7 概念冲突,新增需求点与 T7 卡;T2 的对外文案由「机械换词」改为「按概念两态改写」) -- **迭代归属**:**已编入 roadmap 迭代 32**(`0da014d4`,周期列 ≈0.5 周;开工门=U0 `/iter 32` 用户发令) -- **上游依据**:2026-10-19 用户裁——「完美排雷」**全库统一**换代为「完美封印」,含代码内部注释 - ---- - -## 0 · 概念定义(动笔前必读,本卡所有措辞以此为准) - -**完美封印**(玩家面正式名;机制文档旧称「完美排雷」)= **一张图的清图奖励加倍条件**。 - -| 项 | 内容 | -|---|---| -| 成立判据 | 一张图「零有效误标」**且**「至少一次封印标中」 | -| 有效误标 | = 误标总数 − 豁免数(迭代 31 卡② T4 落的两账相减口径) | -| 计数纯净 | `_perfect_hit_false` 全程不被任何效果改写;豁免只累加 `_perfect_forgiven` | -| 成立效果 | 清图奖励对象追加**第二份同身份**兑付(乘数 `p_perfect`,现行值读 `settlement.tres`) | -| **被破之后** | 不再满足零有效误标 ⇒ 完美封印不成立 ⇒ **清图奖励只发一份,不加倍** | -| 计数起算 | 从装板起算;换图重置 | -| 高光行 | 成立时发一行;首份即零兑付则高光行不发 | - -**出处**: -- 规则本体 — `design/gdd/systems/战斗循环/战斗结算.md:161` -- 当量公式 — 同文件 :108(`完美排雷的清图奖励: E = 奖励表值 × 完美乘数 ÷ 100`) -- 乘数字义 — 同文件 :116 -- 调参表 — 同文件 :321(`完美乘数 | percent {100, 200} | 100 为仅高光、无第二份`) -- 清图批 — 同文件 :139;刷新图重置 — :259 -- 兑付结构 — `design/gdd/systems/战斗循环/地图战斗资源.md:155`/:194 - -**玩家面命名纪律**:术语表「对外命名纪律」禁「雷」字面进对外命名,适用范围**含 UI 文案**;该概念的玩家面正式名=「完美封印」,现由 `design/gdd/systems/冒险循环/奇物.md` v3.18 与 `game/data/tables/feats.tres:861` desc 在用。 - ---- - -## 1 · 目标与完成定义 - -**目标**:把术语表已在册的退役词从 `game/` 的代码注释里清干净,把「完美排雷」统一为玩家面正式名「完美封印」,修掉扫描中查出的归因锚判据矛盾;同时在**代码域自己的静态扫描闸**里补一条规则,让这类残留以后自动见红。 - -| 需求点 | 一句话 | -|---|---| -| **N1** | 「完美排雷」全库统一为「完美封印」(对外文案 3 处 / 其余 18 处:注释、文档正文、断言描述与夹具) | -| **N2** | 注释里「板级」换代为「整图」 | -| **N3** | 注释里「门票」换代为「专长凭证」(标识符与数据键零改动) | -| **N4** | 注释里「正主」换代为「现行事实源」 | -| **N5** | 注释里「落籍」换代为「已入库」 | -| **N6** | 代码域静态扫描闸新增 S11「代码注释禁用词」规则,先落规则再见红 | -| **N7** | 封印未中行的「完美封印已破」归因锚改用**有效误标**判据,文案按「未豁免/已豁免」两态改写 | - -**完成定义**(全部满足才算完): - -1. `game/` 内 `完美排雷`/`板级`/`门票`(注释面)/`正主`/`落籍` 五词,**改后命中行 == §2 显式豁免单(4 处)+移交 3 处,其余为零**(v1.3 起口径=全部命中计入待清、显式豁免逐处列举;移交行非注释面,S11 与 A4 的注释面口径天然不含)。 -2. 对外文案三处不含「雷」字面,读作「完美封印」。 -3. **N7**:装备「完美保险」专长时本战首次标错 → `seal_miss` 行的 `highlight` 字段为 `""`(豁免态,无金框),且 `perfect_sweep_earned() == true`;未装备时首次标错 → `highlight` 为 `"perfect_broken"`(已破态,金框),且 `perfect_sweep_earned() == false`。两态各有正向断言(A10/A11)。 -4. 冒烟绿数与改前基线一致(现行 1151 项 0 失败)、单元测试 34 套全绿、探针段绿。 -5. S11 规则在位:注入一次禁用词 → `game/tests/static_scan.sh` 判红;还原后绿;变异验证记录进实现报告。 -6. 代码域闸按域选档跑通,回执 `game/tests/.gates/receipt.json` 的 commit = 分支 tip 且 `all_green=true`。 -7. `reports/` 三份产出物写齐(实现报告/代拍板追认单/反哺点清单)。 - -**文档面不在本卡完成定义内**——迭代批禁写 `design/` 整目录与根规则文件,唯一可写目录=`reports/`(process-conventions §3 第 13 条)。 - ---- - -## 2 · 现状事实(2026-10-19 实测;v1.3 于 2026-10-20 全量复核——五词原始命中 119 行,开工自行复核) - -扫描范围:`game/` 下 195 个文件(.gd/.tres/.md/.json/.sh/.txt)。 - -**口径(v1.3 重订——废 25 子串信号过滤,改显式豁免单)**:命中行**全部计入待清清单**;显式豁免仅限下列 4 处(逐处列举理由)。v1.2 及以前用的信号子串过滤(`退役`/`作废`/`→`/`历史`/`登记`/`豁免` 等 25 个)实测**误伤 14/17 处活注释**(行内只是行文带了 `→` 或别处主语含「豁免/作废」就被当对照行跳过),且**漏豁免** `enemy.tres:653`(批末 S11+A6 必红)——两面都不靠谱,故废。 - -| 豁免行 | 词 | 理由 | -|---|---|---| -| `game/data/tables/enemy.tres:653` | 落籍 | 带 commit 号(9cc4b8b)的落表留档注记——B1 历史文本(代拍板白名单 2 已裁不改) | -| `game/core/level_runner.gd:832` | 门票 | 迭代 12 T6「渠道分离退役」的历史注记——B1 历史文本 | -| `game/core/adventure_runner.gd:403` | 正主 | T4 F-1 历史修复注记(行内主语=已退役写口 `_attune_refresh_x`;且此处「正主」义为缺陷根因而非权威源,换代反毁句意) | -| `game/tests/unit/battle_settlement/damage_math_test.gd:36` | 正主 | 误报——「正主角池」=正主+角池,非词面命中 | - -**移交 3 处**(不属本批,去向=文档轨批;非注释面,S11 注释面口径与 A4「注释面」口径天然不含,不入豁免单——清单见 §2 N3 节末)。 - -### N1 · 完美排雷(21 处 / 9 文件) - -| 落点 | 行 | 面 | -|---|---|---| -| `core/battle_orchestrator.gd` | 265、911 | 注释 | -| `core/battle_orchestrator.gd` | **925** | **对外文案**(`"完美排雷!清图奖励 ×2"`) | -| `core/battle_orchestrator.gd` | 1296 | `##` 文档注释(谓词说明) | -| `data/schemas/settlement_table.gd` | 8 | 注释 | -| `presentation/row_pacer.gd` | 92 | 注释 | -| `presentation/views/battle_log_view.gd` | **194** | **对外文案**(「本板完美排雷已破」) | -| `presentation/views/board_fx_view.gd` | 2、90 | 注释 | -| `presentation/views/board_fx_view.gd` | **102** | **对外文案**(`_show_banner("完美排雷 ×2")`) | -| `presentation/views/settlement_fx_view.gd` | 14 | 注释 | -| `game/README.md` | 146、168、267 | 文档正文(168=v1 遗留观测项清单、267=全屏 States 与模态段,均活文本;v1.3 补 168/267——旧信号过滤因行内别处含「作废/历史」误伤) | -| `smoke/smoke_all.gd` | 3503、3512、3513、3516、4076 | 注释/断言描述(v1.3 补 3503/3513——旧信号过滤因行内「→」误伤) | -| `smoke/smoke_all.gd` | **6201** | **冒烟夹具期望字面量**(断言比对用,非注释) | -| `tests/smoke/critical-paths.md` | 20 | 文档正文 | - -### N2 · 板级(33 处 / 15 文件) - -`core/battle_orchestrator.gd`(67、265、445、470、482、506、507、928、1213)· `core/board_data.gd`(17、53)· `core/treasure_items.gd`(2、41、63)· `core/minesweeper_rules.gd`(126)· `data/schemas/variation_table.gd`(20、79)· `presentation/main.gd`(914)· `presentation/hud_presenter.gd`(40、105)· `presentation/treasure_interact_controller.gd`(101)· `presentation/views/board_view.gd`(149、511、544)· `presentation/views/board_cell_unit.gd`(97)· `presentation/views/hero_info_panel_view.gd`(122、162)· `presentation/views/settlement_fx_view.gd`(146)· `smoke/smoke_all.gd`(1846、2588、2630)· `smoke/ui_input_probe.gd`(4)· `tests/unit/core/feat_vouchers_test.gd`(174) - -(v1.3 补 7 处 2 文件:`hud_presenter.gd` 全文件、`ui_input_probe.gd` 全文件不在 v1.2 清单内;`battle_orchestrator.gd:445`/`treasure_items.gd:63`/`board_view.gd:544`/`smoke_all.gd:1846` 因行内含「→/禁用/登记」子串被旧信号过滤误伤——全是活注释。) - -### N3 · 门票(39 处 / 12 文件;其中 3 处移交,本批做 36 处) - -`core/adventure_runner.gd`(67、68、69、477、664、751、771、788、796、1033、1034)· `core/level_runner.gd`(51、781、826、831)· `core/config_db_cross_validator.gd`(103)· `data/schemas/adventure_table.gd`(92、96、97)· `data/schemas/shop_table.gd`(18)· `data/tables/shop.tres`(104)· `presentation/curio_interact_controller.gd`(89、217、237)· `presentation/views/curio_pick_overlay.gd`(110)· `smoke/level_autoplay.gd`(226)· `smoke/smoke_all.gd`(1362、1363、1370、1378、1379、1382、1384、5306)· `tests/unit/core/pool_case_d_test.gd`(98)· `tests/unit/presentation/reward_overlay_test.gd`(41) - -(v1.3 补 `config_db_cross_validator.gd:103`——「T5 门票豁免」活注释,旧信号过滤因行内「豁免」子串误伤;`level_runner.gd:832` 入豁免单,见上口径表。) - -**移交 3 处**(不属本批,去向=文档轨批):`data/tables/shop.tres:86` display_name「奇物门票」、`presentation/curio_interact_controller.gd:165`/`:166` 玩家可见文案「奇物门票/开一次奇物三选一」。 - -### N4 · 正主(14 处 / 10 文件,含误报 1 处) - -`core/adventure_runner.gd:59` · `core/treasure_items.gd:57` · `presentation/views/board_cell_unit.gd:111`/`112` · `presentation/views/board_view.gd:122`/`843` · `smoke/board_shot_probe.gd:31` · `smoke/layout_probe.gd:2` · `smoke/shot_probe.gd:3`/`28` · `smoke/t17_defer_probe.gd:6`/`20` · `tests/static_scan.sh:73` · `tests/unit/battle_settlement/damage_math_test.gd:36`(**误报**——「正主角池」是「正主」+「角池」,非词面命中,不改) - -(v1.3 补 2 处:`board_view.gd:843`「正主 :163 照抄」(活注释,旧信号过滤因「→」误伤)、`static_scan.sh:73`「数值单一事实源的正主」(S3 规则头注,活注释;建议随批改为「数值单一事实源自身」一类等价措辞——代拍板 1)。`adventure_runner.gd:403` 入豁免单,见上口径表。) - -### N5 · 落籍(10 处 / 4 文件,含历史注记 1 处) - -`core/config_db.gd`(22、23、42、45、280、337、390)· `data/tables/enemy.tres:653`(**历史注记**——「已落籍 9cc4b8b」带 commit 号,属留档文本,不追改)· `presentation/views/board_view.gd:35` · `tests/unit/data_config/config_db_test.gd:133` - -### N7 · 归因锚判据与概念定义矛盾(真缺陷,本批一并修) - -三个落点构成一条矛盾链: - -| # | 落点 | 现状 | -|---|---|---| -| 1 | `core/settlement/grant_segment.gd:295` | `oc._perfect_hit_false += 1` —— 累加的是 **RAW 误标总数** | -| 2 | `core/settlement/grant_segment.gd:300-301` | `if oc._perfect_hit_false == 1: hl = "perfect_broken"` —— 判据**只看 RAW 计数** | -| 3 | `core/battle_orchestrator.gd:1298-1299` | `perfect_sweep_earned()` 用的却是**有效误标**=`_perfect_hit_false − _perfect_forgiven <= 0` | - -**矛盾实证**:`grant_segment.gd:308-315` 里 `_fx_emit("seal_missed")` 与 `_perfect_forgiven += 1`(:314)都排在 `_emit_row`(:302)**之后**。装备「完美保险」专长时: -- 第 300 行 RAW 计数 `== 1` 成立 ⇒ 打印「完美封印已破」 -- 但第 314 行随后把 `_perfect_forgiven` 加到 1 ⇒ 有效误标 = 0 ⇒ `perfect_sweep_earned()` 仍为 **true**,加倍奖励照发 - -⇒ **日志告诉玩家"加倍没了",实际加倍还在。** 这不是病句,是断言了与真值相反的状态。 - -引用口径:`奇物.md` v3.18 已改用「完美封印」;`feats.tres:861` desc =「本场首次封印落空,不计入完美封印判定」。 - -### 已核实清零(迭代 31 成果,本批不重复动) - -`金币`/`插旗`/`标旗`/`雷格`/`惩罚格`/`工作日志` 在 `game/` 内现行计数**均为 0**(v1.3 复核确认)。残留 6 处「旗」=闸门自指 5 处(`smoke/smoke_all.gd:1319`/`:1321`、`tests/unit/presentation/ui_font_asset_test.gd:18`/`:19`、`data/tables/feats.tres:10`)+更名记载 1 处(`feats.tres:11`「旗〔旧称〕=封印」)——前者由契约 9 自指豁免覆盖,后者属 B2 对照性文本;单字「旗」不入 S11 词表(契约 7 排除单)。另「巢穴」20 处全为玩家可见专名「巢穴预告」与风味层表述(`treasure_items.tres:99`/`main.gd:913` 等),同入排除单;「排雷」64 处 / 26 个文件(「排雷玩法/排雷规则」内部机制名)不扩大禁词面(§10 已裁)。 - -**复现命令**(仓库根):`grep -rn "完美排雷\|板级\|门票\|正主\|落籍" game/ --include=*.gd --include=*.tres --include=*.md --include=*.json --include=*.sh` - ---- - -## 3 · 设计契约(🔴 违反=L3 停机呈报) - -1. 🔴 **标识符零改动**——`feat_ticket_*`(`_feat_ticket_pity`/`_feat_ticket_sold`/`_feat_ticket_appeared`/`_redeem_feat_ticket()`/`_pool_ticket`/`feat_ticket_chance`/`feat_ticket_quota`)、`SHELF_KINDS` 的 `"feat_ticket"`、断点存档键 `"feat_ticket_pity"`/`"feat_ticket_sold"`(持久化在 `save.json` 的 `breakpoint.adventure_counters`)**一律不动**。改名会断旧存档与跨文件契约,且上游 `需求卡片-凭证件裁削批`:109 明列「feat_ticket 体系|与本批无关,不碰」。 -2. 🔴 **对外文案只动三处**——`battle_orchestrator.gd:925`/`board_fx_view.gd:102`/`battle_log_view.gd:194`;其余对外文案(含 `shop.tres:86`、`curio_interact_controller.gd:165-166`)零改动。 -3. 🔴 **语义先行,禁纯词面替换**(grilling 复核门查出后立)——改写玩家可见文案前,必须先读 §0 概念定义并确认这句在讲什么;机检只能判字面,判不了语义对错。 -4. 🔴 **完美封印判据单点**——「是否已破」只允许由 `battle_orchestrator.perfect_sweep_earned()` 的有效误标口径派生,禁在 `grant_segment.gd` 另立 RAW 计数判据;两处口径不一致即为缺陷。 -5. 🔴 **游戏行为零变化**(N1–N5、N7 判据修正前)——纯中文文本替换,禁止改动逻辑、数值、权重、条件判断。N7 判据修正是**本批唯一允许的逻辑改动**,其验收为「日志文案与真值一致」,不改奖励兑付结果。 -6. 🔴 **S11 规则先落、后修码**——先把规则写进 `game/tests/static_scan.sh` 并跑出红,再动注释(code-conventions 缺陷-规范对照表纪律)。 -7. 🔴 **S11 词表=术语表解析+显式排除单,不内联第二份**——词表面从 `design/gdd/术语表.md`「退役词对照」节解析第一列全部词面(去括号注)得 12 个,**显式追加 `完美排雷` 完整短语**(受「对外命名纪律」约束,不在退役词对照表里),再套**显式排除单 2 个**(带理由;排除单是词表的元数据不是第二份词表): - - **排除 `巢穴`**:`game/` 内 20 处命中全为玩家可见专名「巢穴预告」(`treasure_items.tres:99` display_name/`main.gd:913` toast 等)与风味层表述(「惊动巢穴」「巢穴敌」)——术语表该行自带「世界观风味层除外」注,B3 专名豁免;「巢穴(机制表述)」的清理**不在本批范围**(§4 不做),收进来批末 S11 必红 20 处。巢穴机制表述换代需用户裁后另立批。 - - **排除 `旗`**:`tools/doc_term_audit.py` 既有判例「旗单字不入表(词面误报率高——旗帜/红旗等同族误伤)」;`game/` 内 6 处命中=5 处闸门自指(契约 9 覆盖)+1 处更名记载(`feats.tres:11`,B2 对照性文本)。单字旗如需清理随旗概念批另裁。 - **明确不收**:①术语表「用语规范」A 表词面(`不得`/`报错`/`对标`/`若干`/`buff` 等)——§4 已列「不做」,收进来批末必然红;②单字「雷」——会误伤 64 处 / 26 个文件的保留词「排雷玩法/排雷规则」(内部机制名,§10 明定不扩大禁词面)。**禁止在脚本里另抄一份词表**(单一事实源红线,ADR 漂移教训同类)。A 表词/巢穴/旗将来若被裁决纳入,另行扩词表并单独立批清扫。 -8. 🔴 **S11 必须带两道零命中自检**——①扫描面文件数为零即判红;②从术语表解析出的词面数为零即判红(沿 S3 教训:路径写歪或表格结构变了时,自检一起歪、一起红,不会静默恒绿)。 -9. 🔴 **S11 闸门自指豁免**——命中行若属「检查禁用词本身」的闸门形态(行内含 `contains(`/`find(`/`grep`/`has_char(`/`禁「`/`禁『`/`零「`/`零『` 等检查或禁令表述),或含 `doc_term_audit.py` 同源的对照/历史信号,一律豁免、不判红。现存受此豁免的 5 处:`game/smoke/smoke_all.gd:1319`(禁字面检查逻辑)/`:1321`(零「雷/旗」断言描述)、`game/tests/unit/presentation/ui_font_asset_test.gd:18`/`:19`(字形覆盖夹具)、`game/data/tables/feats.tres:10`(desc 禁令引举)。**S11 规则说明自身与登记行一律用禁令引举句式**(如「禁「板级」「门票」……」)——既落 B2 对照性文本豁免,又天然触发本条自指豁免(否则闸本体的头注会被自己判红)。 -10. 🔴 **本批禁碰这两个文件**——`AGENTS.md`(根规则文件)与 `design/engineering/code-conventions.md`(在 `design/` 目录内):依据=迭代批禁写 `design/` 与根规则文件这条流水线红线(process-conventions §2),本批无例外。S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`。 -11. 🔴 **对照性文本豁免**——含退役/更名/禁令等信号的行不改写(术语表用语规范 B 类豁免条款);本批的 B 类落点已全部显式枚举进 §2 豁免单,不再用行内子串现场判定。 -12. 🔴 **parity 闸本批不发起、漂移记档、合回后另立重锚批**——N7 的 `_emit_row` 后移+`hl` 两态化会互换 `seal_miss`/`insurance_used` 两行的日志顺序并改写豁免态 `highlight`(`playtest_logger._on_step_row` 逐行落盘、七公共字段含 `highlight`),而 11 号闸对 JSONL 按 sha256 逐位比对——批准实跑必红,且闸令明载「不得借机重锚」。故本批 **不发起 parity**(回执落 NEED-APPROVAL:该态指纹记 skip、入 not_run,`all_green` 不受影响);预期漂移(豁免态/未豁免态各一例)写进实现报告「已记档差异」节;合回后另立**用户批准**的 parity 重锚批并登记 06,不得借任何批「顺手」重锚。N7 的行为正确性验收走 A10/A11/A12 正向断言(测试三层分工纪律①主力)。 - ---- - -## 4 · 范围边界 - -**做**: - -1. `game/` 内 `完美排雷`→`完美封印`(21 处,含对外文案 3 处) -2. `game/` 内注释面 `板级`→`整图`(33 处) -3. `game/` 内注释面 `门票`→`专长凭证`(36 处,剔除移交 3 处与豁免 1 处) -4. `game/` 内注释面 `正主`→`现行事实源`(13 处,剔除误报 1 处与豁免 1 处) -5. `game/` 内注释面 `落籍`→`已入库`(9 处,剔除豁免 1 处) -6. **N7**:封印未中行归因锚改用有效误标判据,文案按两态改写 -7. 代码域静态扫描闸新增 S11 规则(词表=术语表解析+显式排除单〔巢穴/旗〕+`完美排雷`;含两道零命中自检、闸门自指豁免与 4 处显式留档豁免) -8. `game/README.md`/`game/tests/README.md` 同步 -9. 全量冒烟+单元+探针验证,绿数与基线一致 - -**不做**(去向): - -| 不做的 | 去向 | -|---|---| -| `design/` 全部文档(术语表/战斗结算/地图战斗资源/难度曲线与Boss/art-bible/ux 各件/07 清单) | **反哺点**——落 `reports/iter32-反哺点-<日期>.md`,由用户在会话裁决后归文档轨批(迭代批禁写 `design/`) | -| `门票` 标识符与数据键(`feat_ticket_*`/`SHELF_KINDS`/存档键) | 上游卡 §4 明列不碰;若将来要改,另立独立批并连带处理存档兼容 | -| `shop.tres:86`「奇物门票」与 `curio_interact_controller.gd:165-166` 玩家文案 | 属 奇物/专长 归类表述,与 06「冒记案遗留待裁两项」第①项同源 → 交文档侧定性后另走传导批 | -| `AGENTS.md`/`design/engineering/code-conventions.md` | 本批禁碰——迭代批禁写 `design/` 与根规则文件(流水线既有红线,见契约 10) | -| 术语表 A 表词(不得 14/报错 18/对标 1/若干 1/buff 22) | 待用户另裁;裁入则新立 06 条目与卡片 | -| 「巢穴(机制表述)」换代与单字「旗」清理 | S11 显式排除单已收理由(巢穴=玩家专名 B3+风味层除外注;旗=doc_term_audit 既有判例+6 处全豁免);两项清理均需用户裁后另立批(06 登记) | -| doc-conventions 第 4 节流程动词(收口 128/随批 20/台账 17/对拍 16/在飞 10/落文 2) | 同上 | -| 简明技术中文(STC)通用禁用词(缺省 105/情况 26/入参·出参 23/比较·较为·相对 22 等) | 同上 | -| 任何游戏逻辑/数值改动(N7 判据修正除外) | 禁止 | - ---- - -## 5 · 关联文档同步面(必填) - -| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 | -|---|---|---| -| `design/gdd/术语表.md` | 「退役词对照」节有「门票→专长凭证」行,代码侧换代后该对照行应保留(对照行合法);「完美封印」尚未入表,玩家面正式名应由文档侧登记 | **反哺点** | -| `design/gdd/systems/战斗循环/战斗结算.md`(:85/:108/:116/:139/:141/:161/:259/:342) | 全篇称「完美排雷」,与 `奇物.md` v3.18+ 的「完美封印」同名异称 | **反哺点** | -| `design/gdd/systems/战斗循环/地图战斗资源.md`(:155/:194) | 同上 | **反哺点** | -| `design/gdd/systems/冒险循环/难度曲线与Boss.md`(:224/:227/:313) | 同上 | **反哺点** | -| `design/gdd/systems/战斗循环/战斗表现.md`(:53/:68) | 同上 | **反哺点** | -| `design/gdd/systems/表现与支撑/HUD框架.md`(:277) | 同上 | **反哺点** | -| `design/gdd/ux/battle.md`(:85/:222/:422) | 同上 | **反哺点** | -| `design/gdd/ux/interaction-patterns.md`(:90) | 同上 | **反哺点** | -| `design/art/art-bible.md`(:8/:88/:562/:574) | 同上;另 :198/:211 的「金币」换代 GP 已由分支 `gpsweep-20261019` 完成但未合回 | **反哺点** | -| `design/gdd/07-体验验证清单.md`(:142) | 「完美排雷」措辞;本批对外文案变更需登记目检项 | **反哺点** | -| `game/README.md`(:146/:168/:267) | 措辞换代 | **本批直改**(文件在 `game/` 内) | -| `game/tests/README.md` | S11 规则说明与扫描面登记 | **本批直改** | -| `game/tests/static_scan.sh` | S11 规则承载 | **本批直改** | - ---- - -## 6 · 任务卡 - -### 卡前·文件结构图 - -| 文件 | 职责 | 本批动作 | -|---|---|---| -| `game/tests/static_scan.sh` | 静态扫描域可执行承载(现 S1–S5、S9、S10) | 增 S11 段 | -| `game/tests/README.md` | 测试分层与闸口径登记 | 增 S11 说明 | -| `game/README.md` | 切片架构说明 | 措辞换代 | -| `game/core/battle_orchestrator.gd` | 战斗编排器 | 注释+对外文案换代 | -| `game/core/settlement/grant_segment.gd` | 授予段 | 注释换代 + **N7 判据修正** | -| `game/core/minesweeper_rules.gd` 等 36 个 .gd | 注释承载 | 注释换代 | -| `game/data/tables/*.tres` | 数据表注释 | 注释换代 | -| `game/smoke/smoke_all.gd` | 冒烟断言 | 注释、断言描述与夹具期望字面量换代 | -| `game/tests/unit/**` | 单元测试 | 注释与断言描述换代 | - -### T0 · 基线记录(≈15 min) - -- [ ] 在 worktree 内跑全量冒烟,记录绿数(现行基线 1151 项 0 失败) -- [ ] 跑单元测试,记录套数与绿数(现行基线 34 套全绿) -- [ ] 跑 `bash game/tests/static_scan.sh`,记录现行退出码 0 -- [ ] 跑 §2 末复现命令,存改前命中清单(五词逐处),作为改后零残留的对照 -- [ ] 取证「豁免态下日志仍打印已破」:装 `perfect_insurance` 专长 → 首次标错 → 打印日志行原文 - -**取用**:无(首卡)。 -**产出**:`reports/iter32-实现报告-<日期>.md` 的「改前基线」四数——`baseline_smoke_green:int`/`baseline_unit_suites:int`/`baseline_scan_exit:int`/`baseline_forgiven_log_line:String`。 - -### T1 · S11 规则落闸并见红(≈1.0–1.5h) - -- [ ] 在 `game/tests/static_scan.sh` 头部注释补 S11 说明(规则名+权威出处+扫描面+词表来源+豁免条款;**一律用禁令引举句式**,契约 9 末款) -- [ ] 新增 S11 段:扫描面=`game/` 全域 `.gd`/`.tres`/`.md`/`.json`/`.sh`(迭代 31 V4 四类+`.sh`——闸脚本自身注释面;`.txt` 不收=第三方字体许可证非本仓库文本) -- [ ] 注释文本段按类型取:`.gd`/`.sh` 取 `#` 后文本(整行注释与行尾注释都取);`.tres` 取 `;` 后文本;`.md` 取整行(文档正文即注释面);`.json` 无注释语法——保留扩展名但不产生注释段(V4 先例,`game/` 下 .json 五词现行零命中) -- [ ] 词表面从 `design/gdd/术语表.md`「退役词对照」节解析第一列全部词面(去括号注)得 12 个,**显式追加 `完美排雷`**,套显式排除单 `巢穴`/`旗`(契约 7,理由写在头注);不收 A 表词、不收单字「雷」 -- [ ] 三层豁免依序过:①闸门自指(行内含 `contains(`/`find(`/`grep`/`has_char(`/`禁「`/`禁『`/`零「`/`零『` 即跳过,契约 9);②显式留档豁免单 4 处(§2 口径表:`enemy.tres:653`/`level_runner.gd:832`/`adventure_runner.gd:403`/`damage_math_test.gd:36`);③非注释面行不取(数据值与字符串字面量天然不入段——移交 3 处由此天然不含) -- [ ] 自检一:扫描面文件数为零即 `echo "[static_scan] S11 FAIL: 扫描面为空"` 并 `fail=1` -- [ ] 自检二:解析并套排除单后的词面数为零即 `echo "[static_scan] S11 FAIL: 词表解析为空"` 并 `fail=1` -- [ ] 命中即打印 `file:line + 命中词`,段末 `fail=1` -- [ ] 在 `game/tests/README.md` 的静态扫描登记处补 S11 一行(规则名/扫描面/词表来源/三层豁免条款;同用禁令引举句式) -- [ ] 注入验证:在 `game/core/battle_orchestrator.gd` 某注释里临时写回「板级」一词 → 跑 `bash game/tests/static_scan.sh` 见红并记输出摘要 → `git checkout -- game/core/battle_orchestrator.gd` 精确还原 → 记录进实现报告变异验证表 -- [ ] 反向验证:在 `game/smoke/smoke_all.gd:1319`(禁字面检查行)写回原句 → 跑闸**仍为绿**(验证自指豁免生效)→ 还原 -- [ ] 反向验证二:把排除单里的 `巢穴` 删掉 → 跑闸见红且命中行含 `treasure_items.tres:99`(验证排除单是唯一拦住巢穴的机制)→ 还原 - -**取用**:无。 -**产出**:`game/tests/static_scan.sh` 的 `S11` 段(退出码语义=任一硬失败规则命中即 `exit 1`,与现役同段同规)。 - -### T2 · 完美排雷 → 完美封印(≈1.5h) - -**判据(先立后改,§0 为准)**:这句日志在讲「本图的完美封印资格被这次标错打破 ⇒ 清图奖励不再加倍」。 - -- [ ] `game/core/battle_orchestrator.gd:925` 行内字符串 `"完美排雷!清图奖励 ×2"` → `"完美封印!清图奖励 ×2"` -- [ ] `game/presentation/views/board_fx_view.gd:102` `_show_banner("完美排雷 ×2")` → `_show_banner("完美封印 ×2")` -- [ ] `game/presentation/views/battle_log_view.gd:194` 按两态改写(见 T7,判据修正后语义才成立;此处只落文本占位,不留「已破」字样在豁免态) -- [ ] 其余 18 处(8 处代码注释/文档注释:`battle_orchestrator.gd:265`/`:911`/`:1296`、`settlement_table.gd:8`、`row_pacer.gd:92`、`board_fx_view.gd:2`/`:90`、`settlement_fx_view.gd:14`;4 处文档正文:`game/README.md:146`/`:168`/`:267`、`tests/smoke/critical-paths.md:20`;5 处 smoke 注释/断言描述:`smoke_all.gd:3503`/`:3512`/`:3513`/`:3516`/`:4076`;1 处夹具期望字面量:`smoke_all.gd:6201`)逐处换代(清单见 §2 N1 表) -- [ ] 跑 §2 末复现命令确认 `完美排雷` 零命中 - -**取用**:无。 -**产出**:`game/` 内「完美排雷」零命中;对外文案三处读作「完美封印」。 - -### T3 · 板级 → 整图(≈1.5h) - -- [ ] `game/core/battle_orchestrator.gd` 9 处(67/265/445/470/482/506/507/928/1213)换代 -- [ ] `game/core/board_data.gd` 2 处(17/53)换代 -- [ ] `game/presentation/hud_presenter.gd` 2 处(40/105)+ `game/smoke/ui_input_probe.gd` 1 处(4)换代(v1.3 补——两文件整文件不在旧清单内) -- [ ] 余 11 文件 19 处逐处换代(清单见 §2 N2:treasure_items 2/41/63、minesweeper_rules 126、variation_table 20/79、main 914、treasure_interact_controller 101、board_view 149/511/544、board_cell_unit 97、hero_info_panel_view 122/162、settlement_fx_view 146、smoke_all 1846/2588/2630、feat_vouchers_test 174) -- [ ] 跑 §2 末复现命令确认 `板级` 零命中 - -**取用**:无。 -**产出**:`game/` 内「板级」零命中。 - -### T4 · 门票 → 专长凭证(注释面,≈1.0h) - -- [ ] `game/core/adventure_runner.gd` 11 处注释换代(67/68/69/477/664/751/771/788/796/1033/1034) -- [ ] `game/core/level_runner.gd` 4 处(51/781/826/831)换代(`:832` 为历史注记,豁免单内不动) -- [ ] `game/core/config_db_cross_validator.gd:103` 注释换代(v1.3 补——「T5 门票豁免」活注释;`level_runner.gd:832` 同场豁免见 §2 口径表) -- [ ] `game/data/schemas/adventure_table.gd` 3 处(92/96/97)+ `shop_table.gd:18` -- [ ] `game/data/tables/shop.tres:104` 注释换代 -- [ ] `game/presentation/curio_interact_controller.gd` 3 处(89/217/237)+ `curio_pick_overlay.gd:110` -- [ ] `smoke/level_autoplay.gd:226`+`smoke_all.gd` 8 处+`tests/**` 2 处换代 -- [ ] 复核标识符与数据键零改动(`feat_ticket` 族、`"feat_ticket"` 行族键、存档键) - -**取用**:无。 -**产出**:`game/` 注释面「门票」残留=豁免单 1 处(`level_runner.gd:832`);标识符与数据键保持原样。 - -### T5 · 正主 → 现行事实源(≈0.5h) - -- [ ] 13 处换代(清单见 §2 N4,剔除 `damage_math_test.gd:36` 误报与 `adventure_runner.gd:403` 历史注记;含 v1.3 补的 `board_view.gd:843` 与 `static_scan.sh:73`——后者建议改「数值单一事实源自身」一类等价措辞,代拍板 1) - -**取用**:无。 -**产出**:`game/` 内「正主」残留=豁免单 2 处(`adventure_runner.gd:403` 历史注记+`damage_math_test.gd:36` 误报)。 - -### T6 · 落籍 → 已入库(≈0.5h) - -- [ ] 9 处换代(清单见 §2 N5,剔除 `enemy.tres:653` 历史注记) - -**取用**:无。 -**产出**:`game/` 内「落籍」残留=豁免单 1 处(`enemy.tres:653` 历史注记)。 - -### T7 · N7 归因锚判据修正(≈1.5h) - -**修法(已核实可行,禁另选他法)**:`_fx_emit`(`battle_orchestrator.gd:90-93`)是 `_fx.dispatch` 的**有状态派发**——`forgive_seal_miss` 行走 `when lt 1` 限次并由 `_apply_counter_hit` 记账,**重复调用会重复消费限次**。因此**禁止**"先跑一次 `_fx_emit` 算 `hl` 再在原位置跑一次"的做法。 - -- [ ] 把 `core/settlement/grant_segment.gd:302` 的 `oc._emit_row("seal_miss", ...)` **后移**到 `for h in oc._fx_emit("seal_missed", ...)` 循环(:308-317)**之后**——循环结束后 `_perfect_forgiven` 已就位,判据才有真值可用 -- [ ] 判据改有效误标:`var hl := "perfect_broken" if oc._perfect_hit_false - oc._perfect_forgiven == 1 else ""`(替代原 :300 的 RAW 计数 `oc._perfect_hit_false == 1`) -- [ ] 确认行序调换的零影响:`grep -n "insurance_used\|perfect_insurance" game/smoke/smoke_all.gd` 已实测**零命中**——冒烟未断言这两行的相对顺序,调换不涉断言 -- [ ] **parity 漂移记档(契约 12)**:`playtest_logger._on_step_row` 逐行落盘且含 `highlight` 字段——本修改互换 `seal_miss`/`insurance_used` 两行顺序并改写豁免态 `hl`,11 号闸 JSONL 逐位比对必红;本批不发起 parity,把预期漂移(豁免态/未豁免态各一例,含两行顺序与 `highlight` 取值)写进实现报告「已记档差异」节,供合回后的用户批准重锚批对照 -- [ ] 文案两态:未豁免(`hl == "perfect_broken"`)→ `(本图完美封印已破——清图奖励不再加倍)`;已豁免(`hl == ""`)→ `(首次封印落空已豁免——不计入完美封印判定)` -- [ ] 豁免态**不加金框**——`hl == ""` 时 `battle_log_view.gd:195` 走普通色分支;金框语义=强调负面事件,豁免是正向事件,靠同批已存在的 `insurance_used` 行(:316-317)承载反馈即可。不新增高光标记 -- [ ] 正向断言 A10/A11(见 §7) - -**取用**:T2 的对外文案换代结果。 -**产出**:日志文案与 `perfect_sweep_earned()` 真值一致(装备专长时豁免态不再出现「已破」)。 - -### T8 · 全量验证与产出物落位(≈1.0h) - -- [ ] 跑代码域档验收(按本批改动域选档),确认所选域全绿 -- [ ] 确认回执 `game/tests/.gates/receipt.json` 的 commit = 分支 tip 且 `all_green=true` -- [ ] 写 `reports/iter32-实现报告-<日期>.md`(各卡状态+改前改后读数对照+实机目检总清单+遗留读数义务+**已记档差异节**:parity 预期漂移两例〔豁免态/未豁免态各一:`seal_miss`/`insurance_used` 两行顺序互换+豁免态 `highlight` 取值〕+**06 登记项**:合回后用户批准的 parity 重锚批) -- [ ] 写 `reports/iter32-代拍板-<日期>.md` -- [ ] 写 `reports/iter32-反哺点-<日期>.md`(§5 每条都要有落点) - -**取用**:T1–T7 全部产出。 -**产出**:`reports/` 三份产出物 + 可合回的分支 tip。 - -**估时合计 ≈9.0–10.5h**(v1.3:T3 26→33 处、T2 补 4 处、T4/T5 各补 1–2 处、T1 增反向验证二,T3 估时 1.0→1.5h)。切分预案(超 8h 即生效):T3/T4 各拆「核心层」与「呈现+测试」两卡串行施工;T7 独立成卡可单独验收,必要时可拆出本批另立缺陷批。 - ---- - -## 7 · 验证闸 - -### 逐需求点验收清单 - -| # | 需求点 | 测什么(断言/行为) | 怎么测(落点) | 谁验 | -|---|---|---|---|---| -| A1 | N1 | `game/` 内 `完美排雷` 计数 == 0(全清,无豁免) | grep 复现命令+同脚本口径 | 自动(S11+收尾 grep) | -| A2 | N1 | 对外文案三处文本恰为「完美封印…」,且不含「雷」字面 | 新冒烟断言:取清图高光行 `display_name`,断言 `find("雷") == -1` 且 `find("完美封印") >= 0`;落点 `game/smoke/smoke_all.gd` 清图段。另两处字符串字面量(`board_fx_view.gd:102` banner/`battle_log_view.gd:194` 行)S11 扫不到(只扫注释面)——同段加静态读取断言:读两处源文本行,`find("雷") == -1` 且含「完美封印」 | 自动 | -| A3 | N2 | `game/` 内 `板级` 计数 == 0(全清,无豁免) | 同 A1 | 自动 | -| A4 | N3 | `game/` 注释面 `门票` 计数 == 豁免单 1 处(`level_runner.gd:832` 历史注记);且 `feat_ticket` 标识符与存档键**保持原样** | 同 A1(注释面口径天然不含移交 3 处)+ 断言:`_feat_ticket_pity` 等标识符仍在位 | 自动 | -| A5 | N4 | `game/` 内 `正主` 计数 == 豁免单 2 处(`adventure_runner.gd:403` 历史注记+`damage_math_test.gd:36` 误报) | 同 A1 | 自动 | -| A6 | N5 | `game/` 内 `落籍` 计数 == 豁免单 1 处(`enemy.tres:653` 历史注记) | 同 A1 | 自动 | -| A7 | N6 | S11 规则在位:注入禁用词 → 退出码 1 且输出含 `S11 FAIL`/命中行 | 注入实验,落点 `game/tests/static_scan.sh` | 自动(人工执行一次取证) | -| A8 | 全域 | 冒烟绿数 == 基线 1151、单元 34 套全绿、探针段绿 | 跑所选域档 | 自动 | -| A9 | 全域 | 回执 commit == 分支 tip 且 `all_green=true`,零新增红 | 跑闸后读 `game/tests/.gates/receipt.json` | 自动(合回闸) | -| **A10** | **N7** | **未装备完美保险:本战首次标错 → `seal_miss` 行的 `highlight` 字段 == `"perfect_broken"`,且 `perfect_sweep_earned() == false`** | 新增断言,落点 `tests/unit/core/feat_vouchers_test.gd`(现有专长套件,core 层可直取行字段) | 自动 | -| **A11** | **N7** | **装备完美保险:本战首次标错 → `seal_miss` 行的 `highlight` 字段 == `""`,且 `perfect_sweep_earned() == true`(加倍仍发)** | 同上 | 自动 | -| **A12** | **N7** | 两态文案常量与 `battle_log_view.gd` 呈现一致:`_format_row` 对 `hl=="perfect_broken"` 输出「已破」态、对 `hl==""` 输出豁免态,两态均不含「雷」字面 | 断言落点 `tests/unit/core/feat_vouchers_test.gd`(取行字段后按同一分支规则格式化比对) | 自动 | - -**测试方式两分法**:A1–A7、A10–A12 属能力验证(静态扫描/断言直取数据)与取证实验;A8–A9 为运行期验证。玩家可见文案的最终观感归**用户目检**(登记不阻塞):结算明细中封印未中行的两态文案可读性。 - -**闸口径**:按本批改动域选档跑 `tools/run_all_gates.sh`(本批只触 `game/` 与 `reports/` → 代码域档);跑完写回执。**11 号 parity 闸将落 NEED-APPROVAL**(diff 触 `game/core/settlement/`)——该态指纹记 skip、入 `not_run`,`all_green` 不受影响(契约 12:本批不发起、漂移记档、合回后另立用户批准的重锚批)。 - -**回归措辞模板**:「里程碑步(波/T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试/工具先行孤立验证再并入全套」。 - -### 变异验证(新增判据必做) - -| 变异点 | 注入形态 | 跑的闸 | 期望红 | -|---|---|---|---| -| `game/core/battle_orchestrator.gd:265` 注释 | 写回「板级完美排雷」原措辞 | `bash game/tests/static_scan.sh` | `S11 FAIL` + 命中行输出 | -| 同上对外文案 | `game/core/battle_orchestrator.gd:925` 写回「完美排雷!…」 | 冒烟清图段 | 断言 A2 红 | -| S11 扫描面 | 临时把 `DIR_CORE` 改成不存在目录 | `bash game/tests/static_scan.sh` | `S11 FAIL: 扫描面为空` | -| **N7 判据(反)** | `grant_segment.gd` 判据改回 `_perfect_hit_false == 1`(RAW 计数) | `tests/unit/core/feat_vouchers_test.gd` | 断言 A11 红(装备专长时 `highlight` 应为 `""` 却得 `"perfect_broken"`) | -| **N7 判据(正)** | 判据改成 `_perfect_hit_false + _perfect_forgiven == 1`(符号写反) | 同上 | 断言 A10 红(未装备专长时 `highlight` 应为 `"perfect_broken"` 却得 `""`) | -| **S11 自指豁免** | 去掉 S11 的闸门自指豁免分支 | `bash game/tests/static_scan.sh` | `smoke_all.gd:1319`/`:1321`、`ui_font_asset_test.gd:18`、`feats.tres:10` 判红 | -| **S11 排除单** | 把排除单里的 `巢穴` 删掉 | `bash game/tests/static_scan.sh` | 判红且命中行含 `treasure_items.tres:99`(「巢穴预告」display_name) | - -注入后一律 `git checkout -- ` 精确还原,四件(变异点 file:行/跑的闸/红输出摘要/还原结论)记进实现报告变异验证记录表。 - ---- - -## 8 · 异常分级 - -- **L1(自救)**:单文件漏改致 grep 未过 → 补改重跑该段,不改批结构。 -- **L2(记录继续)**:冒烟绿数与基线偏差 ≤2 且已归因到断言描述文本替换 → 记录偏差原因后继续。 -- **L3(停机呈报)**: - 1. 冒烟绿数下降 >2,或出现逻辑断言红(说明改动触及行为); - 2. `.tres` 加载失败或 schema 不同步; - 3. 改前改后同种子读数不一致; - 4. S11 注入后不变红(判据无效); - 5. 触碰 `AGENTS.md` 或 `design/` 目录下任何文件(迭代批越界——流水线红线); - 6. **N7 后移 `_emit_row` 后,奖励兑付结果与改前不一致**(说明改到了兑付行为,而非只改文案判据)。 - ---- - -## 9 · 代拍板白名单 - -1. 注释换代时的措辞微调(如「板级变异」→「整图变异」vs「整图作用域变异」),语义等价即可。 -2. `落籍`→`已入库` 在带 commit 号的历史注记行**不改**(留档文本)。 -3. `正主` 误报处(`damage_math_test.gd:36`「正主角池」)不改。 -4. 测试断言描述文本的替换措辞,语义等价即可。 -5. S11 规则段的 shell 写法(grep 组合、计数方式),与现役 S 段同构即可。 -6. **N7 两态文案的末字微调**(保持「未豁免=已破、已豁免=不计入」这一因果不变成立即可)。 - -超清单必呈报。 - ---- - -## 10 · 待裁点 - -**零待裁点,开工门=U0(`/iter 32` 发令)。** - -已落裁决四条,卡片据以成文: - -| 裁定 | 结论 | -|---|---| -| 完美排雷 | 全库统一换代为「完美封印」,含代码内部注释——2026-10-19 用户裁;据此推翻 `需求卡片-凭证件裁削批`:108「内部开发用语按 v3.15 纪律保留」半句,卡片条款订正归文档轨批 | -| 排雷(模块名) | **不扩大禁词面**。「排雷玩法/排雷规则」是内部机制名(=扫雷推理层的玩法动作总称,见 `00-游戏概念.md:5`),GDD 目录即 `systems/排雷循环/`,术语表正文在用,26 个文件保持原样 | -| 门票 | 仅换代注释措辞;标识符与数据键零改动;玩家可见两处(`shop.tres:86`/`curio_interact_controller.gd:165-166`)移交文档侧定性 | -| 归因锚判据(N7) | 并入本批:`grant_segment.gd` 封印未中行改判有效误标口径(误标总数 − 豁免数),`_emit_row` 后移到 `_fx_emit` 豁免循环之后使判据有真值可用;文案按两态改写——2026-10-20 用户裁(修法 v1.2 定型:上移豁免累加需重复调用 `_fx_emit` 会重复消费限次,已核实不可行) | - -**禁用词机检闸不扩到 `game/`**(用户裁:代码与文档分开管理);代码侧改用代码域自己的静态扫描闸 S11,词表从 `design/gdd/术语表.md` 解析,不内联第二份。 - -**S11 显式排除单 2 词**(v1.3 工程推导,非用户裁决——依据:术语表该行自带风味层除外注+B3 专名豁免+`doc_term_audit.py` 既有判例):`巢穴`(20 处全为玩家专名「巢穴预告」与风味层表述,机制表述换代需用户裁后另立批)、`旗`(单字误报率高,6 处残留全豁)。A 表词/巢穴机制表述/单字旗将来若被裁决纳入,另行扩词表并单独立批清扫。 diff --git a/reports/需求卡片-效果引擎无状态化批-2026-10-20.md b/reports/需求卡片-效果引擎无状态化批-2026-10-20.md deleted file mode 100644 index 6dc28de1..00000000 --- a/reports/需求卡片-效果引擎无状态化批-2026-10-20.md +++ /dev/null @@ -1,339 +0,0 @@ -# 需求卡片:效果引擎无状态化批(计数器外置·分桶) - -- **日期**:2026-10-20 -- **来源**:06-待办清单「计数器寿命域未统一」条目(2026-10-18 登记,来源=会话提及,设计面=文档轨),设计已闭合推进至待写卡(唯一事实源:`design/research/提案-效果引擎无状态化-2026-10-19.md` v1.2——§3 目标形态、§7 N1–N6 定值、§7.7 采集定值、§7.10 缺口闭合定值) -- **批性质**:工程直入类·架构重构(restructure)——代码域批,禁写 `design/` 整个目录与根规则文件,产出物只落 `reports/` -- **估时**:≈4.5–6.25d(=T0–T8 加总;超盒切分预案=T7 拆「断言新增/迁移」与「复放比对」两波先后挂,T3 与 T7 测试迁移互不阻塞可并行切) -- **状态**:成文待审——零待裁点(对抗复核六项已裁并并入正文,见 §12),开工门=U0(用户发令) - ---- - -## 1. 目标与完成定义 - -把 `EffectEngine` 从「解释器+自带状态计数器容器」改为**纯计算引擎(零运行时状态)**:效果侧计数器按 round/battle/level/adventure 四只桶外置、由各生命周期的宿主对象持有(寿命随宿主生灭,不需要寿命字段),事件触发时经 ctx 参数传入,引擎只做判定;计数器归属用 id 前缀表达并加载期强校验。 - -**完成定义**(全部满足才算完): - -1. `EffectEngine` 实例内无任何运行时可变数据(仅剩编译产物 `_triggers` 与只读依赖 `db`); -2. 计数器四桶外置:round/battle 桶挂 `BattleOrchestrator`、level 桶挂 `LevelRunner`、adventure 桶挂 `run_ledger.adventure_counters`,桶随宿主生灭; -3. 搬运链整段删除:`counters_export`/`counters_seed`(引擎)与 `counters_seed_snapshot`/`counters_merge_export`(RunLedger)零残留; -4. `adventure_runner.gd:838-841` 硬编码清除名单(`_reset_tree_limited_counters`)删除,按关清零由 LevelRunner 每关 new 天然承载; -5. 计数器归属机器可读且加载期可校验:`.tres` 行(errs→加载致命)与树合成行(`_push_trigger` assert)双落点,写错前缀即致命;另加装载期**引用闭合**——凡被读到的计数器 id(`when` 内 `fact: counter` 的 `id`/`do.value_counter`/`counter_spend` 的 `counter_id`)必须能在声明集(feats 行+秘宝行+树合成行的 `do.counter_id`)里找到同名写入行,找不到即加载致命; -6. 批内同种子复放比对按三组判读通过(V12):**off 组**(`feat_mode=off`)RUNSUM 全字段逐位一致;**formed 组**(`formed`)与 **rules 组**(`rules`+sense 两键)输入面字段与字段集恒等、局数与种子集一致、零崩溃;输出面差异与 `levels_cleared` 方向只记报告不作判据——**不声称零漂移**(三处已定性预期差异见契约 1); -7. `dig_combo` 死读数连同 combo 分支删除,零行为差(§7.10.14); -8. 旧档断点含旧计数键加载不崩(V13,无迁移——2026-10-18 代码术语刷新批先例)。 - -## 2. 设计事实源 - -`design/research/提案-效果引擎无状态化-2026-10-19.md` **v1.2**(2026-10-20 设计闭合版)——本卡全部设计定值的唯一出处: - -- 目标形态与四桶表=提案 §3(3.1 宿主定值/3.2 接口定稿/3.3 前缀归属); -- N1–N6 定值=提案 §7;不发起全冒险模拟采集=提案 §7.7(零数值改动=零采集——本批唯一例外是 V12 的复放采集,见 §12 裁点①);搬运链缺陷全解=提案 §7.8; -- 写卡前缺口闭合定值=提案 §7.10(ctx 结构/容器类型与测试接口/前缀校验双落点/写口静态化/施加面补列/改名传播面/保险双账不改面/A1 注入口径/level 桶接口/复放分组判读/mine_hit 构造/dig_combo 删除/H1 补条)。 - -与 06 条目状态里的闭合凭据一致(v1.2)。 - -**与本卡口径不一致的提案节以本卡为准**,三处冲突及裁决见 §12:§7.10.3 前缀判据(封闭词表方案在现实 id 面上误伤全部既有 battle id)、§7.10.12 复放判读(所记 27 字段与实采 33 字段不符,且单一「不得上行」判据把增强组与削弱组混判)、§7.7 零采集定值(现行锚与本批不同构,不可用作复放基线)。实现批禁写 `design/`,三处订正随反哺点清单归文档批。 - -## 3. 现状事实(2026-10-20 代码级实查,开工自行复核) - -**引擎侧**: - -- `game/core/effect_engine.gd:83-88` 五成员:`_triggers`(:83,编译产物,留)、`_counters`(:84,运行时容器,搬走)、`_reset_on_round_start`(:85)/`_adventure_counter_ids`(:86-87 含续行,编译名单,随分桶删除)、`db`(:88,只读,留)。 -- 接口与调用点:`rebuild()` :98;`dispatch()` :208(调用点 6 处——`battle_orchestrator.gd:91` `_fx_emit` 汇聚面/`damage_controller.gd:78` `_fx_hits` 汇聚面/`action_economy.gd:103/:164/:191`/`reward_economy.gd:65`);`counter()` :224(外部读 4 处:`battle_orchestrator.gd:638`、`damage_controller.gd:345`、`grant_segment.gd:103/:205`);`counter_add()` :228(写 6 面:`action_economy.gd:108/:111/:169`、`damage_controller.gd:351/:464`、`grant_segment.gd:327`);`counter_spend()` :237(`battle_orchestrator.gd:714` 受理闸);`counters_export()`/`counters_seed()` :246/:255;`validate_trigger_row()` :351(静态,`data/schemas/feat_table.gd:44`、`treasure_item_table.gd:104` 消费)。 -- round_start 清零在 `dispatch` 特判内(:210-212 按名单清零);真实发射点=`battle_orchestrator.gd:97 _emit_round_start()`(调用点 `:425` 首轮/`:1077` 续轮)。 -- `DO_KEYS` :72-75 含 `domain`/`reset_at` 两键;树合成行 `:136-155` 硬编码 `tree_sense_sharp_used`/`tree_sense_guard_used`(走 `_push_trigger`,现仅 assert 事件域——前缀零校验)。 - -**搬运链与自锁**:`run_ledger.gd:40-45` `counters_merge_export` 判空早退(:42)⇒ 全新开局 adventure 域四枚整局不写入(断点回填 :206-208 是唯一解锁路径);战末导出在 `battle_orchestrator.gd:1122-1123`,战首回灌 `:390`。 - -**宿主侧**:`battle_orchestrator.gd:271` `_fx = EffectEngine.new`(_init :268-292 段内 `set_fx` 三处注入 :280-282);`begin_battle` :372-373 `_ledger = enc["ledger"]` 或缺省新账;`level_runner.gd:450-482` `_start_battle` 每战 new 编排器、enc 装配(:471 `"ledger"` 下传行);`adventure_runner.gd:843-845` 每关 new LevelRunner+调 `_reset_tree_limited_counters`;`:255` 新冒险置空 `run_ledger.adventure_counters = {}`;断点写键 `:1033`/回填 `:206-208`。 - -**保险双账**:`grant_segment.gd:311-317` 同一标错分支内 `_perfect_forgiven` 加一(:314)与 `_apply_counter_hit` 落 `insurance_used`(:315→:327)**同点双记各司其职**——前者供判定段两账相减、后者供 when `lt 1` 限次闸;本批不改面(V25 迁移保绿即证)。 - -**死路**:`battle_orchestrator.gd:635-647` `_feat_yield_adjust` 读 `dig_combo`(全仓无数据行声明——feats.tres/treasure_items.tres/树合成行三源零命中;feats.tres 唯一 `"cap"` 行属石肤 ac_bonus `:576-583`,yield_mult 带 cap 行零个)⇒ `combo_val` 恒 0、`combo_cap` 恒 ≤0,分支恒短路。 - -**数据行**:`feats.tres` 计数 id 共 14 枚+树合成 2 枚=16 枚,**14 枚全含下划线**(`round_digs`/`round_mines`/`round_blast_spent` 三枚既有 id 已自带 `round_` 前缀);`reset_at: round_start` 恰 4 行(`round_blast_spent` :212/`instinct_atk` :494/`round_mines` :518/`round_digs` :723——三枚 round_ 前缀行现役已按轮始清零、改名零涉及,分桶后「整桶清空」与现役名单清零逐键等价);`domain` 键行:`twin_digs` :31/`pain_layers` :377/:535/:628(另 :407 附近 set 行)/`insurance_used` :877(battle)。**写点与读点成对同名**:`twin_digs` 写 :29/读 `when.id` :39;`instinct_atk` 写 :492/读 `value_counter` :501——改名必须成对同改,只改写点会把读写拆进两只桶且前缀校验查不出。 - -**残留 `domain` 键两处**:`effect_engine.gd:145/:155` 树合成行与 `tree_rules_v11_test.gd:33/:39` 夹具行仍带 `"domain": "adventure"`——`DO_KEYS` 删键后该夹具在 `validate_trigger_row` 面当场转红,在 T6 一并清除。 - -**过期注释面**:`effect_engine.gd:42`(「feats.tres 首例 domain=battle 行」)/`:70-71`(domain 键说明)/`:118-120`(adventure 域计数器按关重置叙述)、`grant_segment.gd:307`(「限次=合成行 adventure 域计数器闸」——sense 两键改 level 桶后失义)、`run_ledger.gd:7-8` 与 `:12`(export/seed 时点语义、「rebuild 回灌/战末导出回写目标」字段注)、`level_runner.gd:630`(T1 已列)——分桶后字面全部失义,在 T6 一并清除。 - -**采集器与复放数据面(2026-10-20 实跑复核)**:现行锚 `runsum_m3iter9exit_81000_n400_20261003.jsonl` 是 24 字段面、无 `feat_mode`/`attune`/`equipped`/`seal_miss`,与现役采集器的 33 字段面不同构;`sim-data/` 整目录不入 git,批 worktree 内本就没有该文件——两条合起来判锚不可用作本批复放基线,改批内重采(T0/T7)。另查出采集器缺陷:`adventure_monte_carlo.gd:65` 的 `rules` 档用 `String.split()` 产出 `PackedStringArray`,被 `adventure_runner.gd:118/:200` 的 `is Array` 守卫整组静默丢弃——对照实跑为 `ab_a`(字面量 Array)逐局改变轨迹、`rules` 与 `off` 除 `feat_mode` 标签外逐位相同;不修此行则 V12 的 rules 组恒假绿(修复列 T0 首提交)。 - -**静态扫描面**:`static_scan.sh:20-24` 的扫描路径单点只有 `game/core` 与 `game/presentation`,`scan_files` 只数 `.gd`——`feats.tres`、`game/tests/`、`game/smoke/` 全不在面内,新 S 段必须自带扩面(T7),否则「全仓零命中」是空转出来的绿。 - -**测试面**:`tests/run_all.gd` manifest(负面套件协议 `expect:1`+`negative:true`,先例 `reward_dangling_treasure_test.gd` 夹具注入);`tests/README.md:58` 记套件数 26;`game/presentation/` 全目录 counter_id 与 16 枚 id 字面零命中(呈现层不入改名传播)。 - -## 4. 设计契约(违反即返工;🔴 触碰=L3 停机呈报) - -1. 🔴 **确定性**:除三处已定性行为变更(①adventure 桶真跨战持久;②天赋树锋/守真每关限 2;③旧档续玩时 `pain_layers` 不再跨战携带——见契约 8)外,同种子复放必须逐位一致——读写时序、装载序、命中序零变化;命中序=装载声明序写死不碰。全新开局不受③影响(缺陷态下本就未跨战,提案 §7.8 自锁)。 -2. 🔴 **数值零改动**:本批不改任何数值表值;天赋树锋/守「每战 2→每关 2」是回到设计意图(`effect_engine.gd:137` 注释),不是平衡调整;禁顺手调任何 provisional 值。 -3. 🔴 **round 桶就地清空**:轮始清零必须 `.clear()`(或等效就地清空),**禁 `= {}` 重赋值**——重赋值会切断 ctx 持有的引用。 -4. 🔴 **搬运链删除后禁留任何副本同步时点**:战末导出/战首回灌/判空守卫三类代码不得以任何形态复活(含「防御性保留」)。 -5. 🔴 **保险双账不改面**:`_perfect_forgiven` 与 `insurance_used` 同点双记关系原样保持(§3 现状事实),禁合并、禁迁账、禁改判定段两账相减语义(N6 定值)。 -6. 🔴 **两落点同源**:前缀校验的判定函数唯一(静态单点),`validate_trigger_row` 与 `_push_trigger` 共用;禁两处各写一份前缀表。引用闭合校验(T5)只做「读点 id ∈ 声明集」的成员判定,**禁在其中再写一份前缀判据**——前缀归桶的唯一出处仍是 `bucket_of`。 -7. 🔴 **容器与接口逐字锁定**:`EffectContext` 四字段名 `round_bucket`/`battle_bucket`/`level_bucket`/`adventure_bucket`;编排器成员 `fx_counters_round`/`fx_counters_battle`/`counters_ctx`;LevelRunner 成员 `level_counters`;enc 下传键 `"level_counters"`;改名 4 枚新 id `adv_twin_digs`/`lvl_tree_sense_sharp_used`/`lvl_tree_sense_guard_used`/`round_instinct_atk`。实现期不得另起名。 -8. 🔴 **pain_layers 归 battle**:只改归属(删 `domain` 键),单战内「攒层→下次攻击附加→用后清零」行为逐位不变(N4)。跨战口径按设计意图统一为「不跨战」:全新开局本就如此(`run_ledger.gd:42` 自锁),旧档续玩经 `adventure_runner.gd:206-208` 回灌后原可跨战携带,改后不再携带——该差异属缺陷消解(契约 1 第③项),不是语义回归,V13 旧档夹具须带 `pain_layers` 旧键。 -9. 🔴 **旧档不迁移**:改名后旧档断点旧键成死键属预期(H1 只断言不崩);禁加迁移体、禁动 `SAVE_FORMAT_VERSION`。 -10. 🔴 **实现批禁写 `design/` 与根规则文件**;`sim-data/` 只允许 V12 的两次采集(批前三组 40 局基线——已采完留盘,见 T0;批后同种子复放 40 局),二档上限内;现行锚与读数文件一律不动、不改名、不替换;对 `sim-data/README.md` 纪律③⑦的批次例外,依据见 §12 裁点①。 -11. 🔴 **同名成员禁遮蔽内建**:ctx 字段名已避讳(`round_bucket` 非 `round`),实现期引入新成员时同规。 - -## 5. 范围边界 - -**做**:§1 完成定义 1–8 全部;`EffectContext` 新类;引擎接口 ctx 化与写口静态化;7 个施加点迁移;前缀校验双落点+装载期引用闭合校验;4 枚 id 改名(写点与读点成对)+`domain`/`reset_at` 键删除(含引擎合成行与测试夹具两处残留);七处过期注释清扫;`dig_combo` 死路删除;采集器 `rules` 注入类型缺陷修复(一行,T0 首提交);测试新增/迁移/变异验证;批内同种子复放比对(三组 40 局基线已采+40 局复放+`tools/parity_compare.py` 判读);`static_scan.sh` 新增 S11 段(扫描面自带扩至 `game/**` 含 `.tres`)+`run_all.gd` manifest 登记。 - -**不做**(去向已定): - -| 不做项 | 去向 | -|---|---| -| `charge_reset`(秘宝充能周期)、凭证件裸标量、SaveManager meta 域 | 提案 §9 已排除,不动 | -| 断点快照结构(level 桶不进断点——N3:写入时刻恒空,「进」是空操作) | 不动;「退菜单续玩可刷新每关限次」属既有行为,登记真人检测面(V14 目检项) | -| 编排器 5 个效果运行态(`_fx_ac_round`/`_fx_ac_battle`/`_fx_new_resource_types`/`_fx_bonus_delta`/`_perfect_forgiven`) | N6 定值:只归计数器,留编排器 | -| 天赋树锋/守重新定价 | 独立议题,不进本批(§4.5 B3) | -| architecture.md「系统无状态」原则补条 | 已登记 06 新条目(文档轨·待文档设计),归文档批;本批反哺点带依据 | -| `roadmap.md`「当前位」三行 | 实现批不动——该节由编排段与批末登记维护(本卡编入迭代 32 时已由编排段同步) | -| 与同迭代卡①(代码注释禁用词清扫批)并行开工 | 禁并行:两批都改写 `effect_engine.gd`/`grant_segment.gd`/`run_ledger.gd` 等文件的注释面,本批开工须排在卡①合回之后(roadmap 迭代 32 行执行序①→②) | -| MC 采集(V12 复放之外的任何档) | §7.7 定值:零数值改动=零采集——本批只跑 V12 的三组 40 局基线(已采完)与 40 局复放,不开任何读数档、不动现行锚与读数文件 | -| 元素类型精化(`Dictionary[String, int]`) | S9 现行口径 `Dictionary[Variant, Variant]` 合格,精化另走裁决 | - -## 6. 关联文档同步面(实现批禁写本表所列文档——义务全部走 `reports/iter-反哺点-<日期>.md`) - -| 文档 | 关联点(本批实现改变它的哪条陈述) | 同步义务 | -|---|---|---| -| `design/engineering/architecture/architecture.md` | ①模块归属表 effect_engine 行「对外暴露」列记 `counters_export·counters_seed` 与「domain=adventure 跨战斗持久」(:116)——改后均不存在;②战斗域装配现状节「战末 export/开局 seed 时点语义不变」(:125)随搬运链删除失义;③「架构原则」节缺「系统无状态」条目(立项判据补条) | 反哺点清单逐条列出(①②改写成 ctx 形态描述、③指向 06 在册条目「效果引擎系统无状态原则缺架构文档条目」),用户裁决后归文档批 | -| `game/tests/README.md` | :58 记「manifest 已登记实跑 26 套件」——本批新增 1 负面套件 | 反哺点(机械面文档,批后由文档批更新套件数与段描述) | -| `design/gdd/06-待办清单.md` | 上游条目「计数器寿命域未统一」随批完成整条删除(收口=batch-closure 技能);条目现状内引用的行号(:838-841 等)随实现漂移 | 批内不动;收口时整条删除(行号订正随之消亡) | -| `design/gdd/07-体验验证清单.md` | 天赋树锋/守第二次后无减免=玩家可感知削弱,需真人目检入册 | 反哺点(登记项见 §9 真人目检面) | -| `design/research/提案-效果引擎无状态化-2026-10-19.md` | 三处与本卡口径不同(裁决见 §12):①§7.10.3「`meta_` 及其余未知前缀→违例」——14 枚 id 全含下划线,该判据误伤全部既有 battle id,且封闭前缀词表=第二事实源;②§7.10.12 记「RUNSUM 共 27 字段」且「受影响局 `levels_cleared` 不得上行」——实采 33 字段,且双管镐组是增强方向,单一判据把增强组与削弱组混判;③§7.7「零采集」定值所依赖的现行锚与本批不同构,不可作复放基线 | 反哺点清单逐条列出(本卡为准,提案随文档批订正;`design/` 对本批只读) | -| `sim-data/README.md` | 配套纪律③「对拍断言=0 新跑」与⑦「零数值改动=零 MC」在本批开例外(三组 40 局基线+40 局复放,二档上限内);「现行锚」节与本批复放无关 | 反哺点(登记批次例外与判据,不改档位表本身) | -| `design/gdd/术语表.md` | 零关联(本批不造新术语;四桶/前缀均为代码标识符非玩家术语;未新增 `battle_` 前缀词) | 无 | - -## 7. 卡前文件结构图 - -**新建**: - -| 文件 | 职责 | -|---|---| -| `game/core/effect_context.gd` | `EffectContext`——四桶引用束(RefCounted,四公开类型化字段,零方法) | -| `game/tests/unit/data_config/counter_prefix_fatal_test.gd` | E1 负面套件:坏前缀 counter_id 行→load_tables 拒绝 + 读点 id 无声明行(引用闭合)→load_tables 拒绝(expect 1,两断言同套件) | -| `tools/parity_compare.py` | V12 复放比对器:解析 `RUNSUM` 行按 seed 配对;`--mode parity`(整条记录逐位相等)与 `--mode input-parity`(输入面八字段+顶层字段集恒等)两判据;`--expect <局数>`;输出差异表与 `levels_cleared` 直方图(后者仅报告)。退出码 0 绿/1 红/2 用法或解析错;字段集从基线文件推导,禁硬编码 | - -**修改**: - -| 文件 | 改动 | -|---|---| -| `game/core/effect_engine.gd` | 删三状态成员与搬运接口;dispatch/counter 带 ctx;写口改静态纯函数+`bucket_of`;`_push_trigger` 前缀校验;DO_KEYS 删两键;合成行(:136-155)id 改名**并删 :145/:155 两处 `"domain": "adventure"`**;:42/:70-71/:116-122 过期注释改前缀口径 | -| `game/core/battle_orchestrator.gd` | 两桶公开成员+ctx 构造挂载;set_fx 扩参;`dig_combo` 死路删除;战末导出两行删除 | -| `game/core/action_economy.gd` | set_fx 扩参;3 dispatch 面+3 写口静态化 | -| `game/core/damage_controller.gd` | set_fx 扩参;dispatch 汇聚面+1 读 2 写静态化 | -| `game/core/reward_economy.gd` | set_fx 扩参;dispatch 面加 ctx | -| `game/core/settlement/grant_segment.gd` | `_apply_counter_hit` 静态化;2 读口 ctx 化;`combo_cap` 收集与实参删除;:307「限次=合成行 adventure 域计数器闸」注释改 level 桶口径 | -| `game/core/run_ledger.gd` | 删 `counters_seed_snapshot`/`counters_merge_export`;:7-8 头注契约句与 :12 字段注(「rebuild 回灌/战末导出回写目标」)改 ctx 直写口径 | -| `game/core/adventure_runner.gd` | 删 `_reset_tree_limited_counters` 及调用点 | -| `game/core/level_runner.gd` | `level_counters` 公开成员+enc `"level_counters"` 下传 | -| `game/data/tables/feats.tres` | 4 枚 id 改名(**写点 :29/:492 与读点 :39/:501 成对同改**);`domain`/`reset_at` 键逐行删除 | -| `game/core/config_db_cross_validator.gd` | 新增计数器引用闭合校验(声明集 vs 读点集,违例入 errs→加载致命) | -| `game/smoke/adventure_monte_carlo.gd` | `:65` `rules` 档类型修复(`split` 结果包 `Array(…)`、`split(",", false)`)——T0 首提交,V12 rules 组生效前提 | -| `game/tests/static_scan.sh` | 新增 S11 段:旧件符号+带引号旧 id 字面零命中;**扫描面自带扩至 `game/**/*.gd` 与 `game/data/tables/*.tres`**(现役 :20-24 只覆盖 core/presentation 的 `.gd`,不扩面即空转)+扫描面非空自检 | -| `game/tests/run_all.gd` | manifest 登记负面套件 | -| `game/tests/unit/core/effect_words_t1_test.gd` | ⑥ export/seed 块、⑦ reset_at/spend 块重写为桶语义;裸 dispatch/写口 ctx 化 | -| `game/tests/unit/core/tree_rules_v11_test.gd` | :29-39 合成行字面 id 随改名+**删 :33/:39 两处 `"domain": "adventure"`**(不删则 `validate_trigger_row` 面当场转红) | -| `game/tests/unit/core/feat_vouchers_test.gd` | V16 键名随前缀;V25 迁移保绿;新增 H1 旧档不崩断言 | -| `game/tests/unit/core/settle_segments_test.gd` | `:32-33` 样本 id 换活 id+ctx 形态 | -| `game/tests/unit/core/treasure_effects_test.gd` | 裸 dispatch 面 ctx 化(:34/:45/:53-56) | -| `game/smoke/smoke_all.gd` | 新增 V1–V6/V8/V12 冒烟断言段;`:6076-6083`/`:6124-6128` 旧链删除;`:1419-1602` 裸引擎段 53 处 dispatch+8 处写口改 ctx 形态;各 rig enc `"adventure_counters"` 死键清除;`:1610` rebuild 调用零迁移 | - -## 8. 任务卡 T0–T8 - -### T0 基线(0.25d) - -- [ ] worktree/分支开工(process-conventions §1);拷主区 `.godot/` 与字体 `.import` 边车 -- [ ] **首提交=采集器 `rules` 注入类型缺陷修复**:`adventure_monte_carlo.gd:65` 的 `String(args[7] if args.size() >= 8 else "").split(",")` 改为 `Array(String(args[7] if args.size() >= 8 else "").split(",", false))`(不包则 `PackedStringArray` 被 `adventure_runner.gd:118` 的 `is Array` 整组静默丢弃——实测 `rules` 档与 `off` 逐位相同);单独一个提交,提交信息注明「测试工具类型修复,无玩法改动」 -- [ ] 基线三查记档:冒烟全绿数目、单元 26 套件全绿、探针基线 -- [ ] **V12 批前基线=卡片成文后的准备阶段已采完,批内不重跑**:三组文件(`sim-data/v12_base_off_n20_81000_f75acc1.jsonl` 20 局 81000–81019,sha256 `bf084ef3…`/`sim-data/v12_base_formed_n10_81000_f75acc1.jsonl` 10 局 81000–81009,sha256 `2d3d4247…`/`sim-data/v12_base_rules-sense_n10_81000_f75acc1_p1.jsonl` 10 局 81000–81009,sha256 `0fcbcb26…`,`_p1` 后缀=依赖上一条采集器修复),主区 `sim-data/` 与卡片 worktree `sim-data/` 两处留盘(`sim-data/` 不入 git,实现批新 worktree 内无此目录——开工时从主区拷入本 worktree 的 `sim-data/`,或让比对器按绝对路径读主区文件);采集时工作区无改动,有效码=commit `826e7ea1` 的 `game` 树 `f75acc15…` +本 T0 首提交。**开工先核 `git rev-parse HEAD:game`**:若不等于 `f75acc15…`(master 的 `game/` 在准备阶段之后前进过),留盘基线作废,按 T7 命令重采三组 40 局 -- [ ] `git log --oneline -1` 与 `tools/run_all_gates.sh --code` 基线档记档(起点绿态) - -**产出**:基线档(实现报告 T0 节)。 - -### T1 `EffectContext` 新建+四宿主接线(0.5–1d) - -**取用**:无。**产出**:`EffectContext`(字段名见契约 7)——T2–T7 全部引用。 - -- [ ] 新建 `game/core/effect_context.gd`:`class_name EffectContext extends RefCounted`;四字段 `var round_bucket: Dictionary[Variant, Variant] = {}`(battle_bucket/level_bucket/adventure_bucket 同型);文件头注 ≤8 行两类白名单;跑一次编辑器扫描刷新全局类缓存(code-conventions §4.5) -- [ ] `BattleOrchestrator` 增三公开成员:`fx_counters_round`/`fx_counters_battle`(`Dictionary[Variant, Variant]`)+`counters_ctx: EffectContext`;`_init` 内构造 ctx 并挂自有两桶引用 -- [ ] `LevelRunner` 增公开成员 `level_counters: Dictionary[Variant, Variant]`;`_start_battle` enc 增 `"level_counters": level_counters`(`"ledger"` 行 :471 后);:630 过期契约注释(「战斗侧只走账类原语,战末 export/开局 seed」)随批改写 -- [ ] `begin_battle` :373 后挂载:`counters_ctx.adventure_bucket = _ledger.adventure_counters`;`enc.get("level_counters")` 为 Dictionary 时 `counters_ctx.level_bucket = enc["level_counters"]`(缺省=调试/单场空桶,与 `_ledger` 缺省新账同式) -- [ ] `set_fx` 三处扩参:`func set_fx(fx: EffectEngine, ctx: EffectContext) -> void`(action_economy.gd:48/damage_controller.gd:70/reward_economy.gd:23),三协同件各增 `_ctx` 成员;`battle_orchestrator.gd:280-282` 调用点同步 -- [ ] 删 `adventure_runner.gd:838-841` `_reset_tree_limited_counters` 与 `:845` 调用点(同批摘除冒烟 `:6125` 直呼——F2 面随 T7 断言同轮) -- [ ] 孤立验证:`--headless --script` 最小驱动 `EffectContext.new()`+编排器 `_init` 构造 ctx 成功(新码先行孤立验证纪律) - -### T2 引擎删状态+ctx 接口+静态写口(0.5–1d) - -**取用**:T1 的 `EffectContext`。**产出**:引擎新接口面——`dispatch(ctx, event, payload, facts)`/`counter(ctx, id)`/`static bucket_of(ctx, id)`/`static counter_add(ctx, id, value, set_mode=false)`/`static counter_spend(ctx, id, value) -> bool`。 - -- [ ] 删成员 `_counters`/`_reset_on_round_start`/`_adventure_counter_ids`(:84-87 含续行)与 rebuild 内三处清零/收集(:100-101/:156-157/:181-190) -- [ ] `rebuild()` 签名不变(`feat_ids, item_ids, tree_rules`)——冒烟 `:1610` 调用面零迁移 -- [ ] `dispatch(ctx: EffectContext, event: String, payload: Dictionary, facts: Callable = Callable()) -> Array`;round_start 特判(:210-212)改 `ctx.round_bucket.clear()`——**就地清空**(契约 3) -- [ ] `counter(ctx: EffectContext, counter_id: String) -> int`(读 `bucket_of(ctx, counter_id)`) -- [ ] 新增 `static func bucket_of(ctx: EffectContext, counter_id: String) -> Dictionary[Variant, Variant]`:`round_`→round_bucket/`lvl_`→level_bucket/`adv_`→adventure_bucket/其余→battle_bucket(前缀规则唯一出处) -- [ ] 新增静态 `counter_add`/`counter_spend`(签名见产出块;算术与阈值闸语义从现役 :228-242 逐字保留);删实例版两方法与 `counters_export`/`counters_seed`(:246-257) -- [ ] `run_ledger.gd` 删 `counters_seed_snapshot`(:36-37)与 `counters_merge_export`(:40-45);头注契约句「战斗侧只走 read/append 两族原语」同步改写(ctx 直写后字面失义、签名可见显式引用的立意由 EffectContext 承接) -- [ ] `DO_KEYS` 删 `"domain"`/`"reset_at"`(:72-75) -- [ ] 孤立验证:裸引擎 rig `EffectEngine.new(null)`+自建 ctx,合成一行 counter_add 行 dispatch→静态写口→counter 读回一致 - -### T3 施加点改写+dig_combo 死路删除(0.5–1d) - -**取用**:T2 全部接口。**产出**:生产侧零 `_fx.counter_add(`/`_fx.counter_spend(`/`counters_export` 残留(V10 静态扫描可证)。 - -- [ ] `action_economy.gd`::103/:164/:191 dispatch 加 `_ctx`;:108/:111/:169 写口改 `EffectEngine.counter_add(_ctx, ...)`——:103-108「counter_spend 订阅→加收对价+积计数」读-判-写序列逐字保留(§7.10.6) -- [ ] `damage_controller.gd`::78 dispatch 加 ctx;:345 读改 `EffectEngine.counter(_ctx, ...)`;:351/:464 写口静态化 -- [ ] `reward_economy.gd`::65 dispatch 加 ctx -- [ ] `grant_segment.gd`::103/:205 读口 ctx 化(经 `oc.counters_ctx`);:327 `_apply_counter_hit` 内写口改静态(调用点 :66/:122/:156/:215/:264 零改动);:54/:61/:62 `combo_cap` 收集与实参删除 -- [ ] `battle_orchestrator.gd`::88 `_fx_emit` 加 `counters_ctx`;:714 受理闸改 `EffectEngine.counter_spend(counters_ctx, ...)`;:390 回灌调用 `_fx.counters_seed(_ledger.counters_seed_snapshot())` 连同 :389 注释行删除;:635-647 删 `dig_combo` 死读数+combo 加成分支+`_feat_yield_adjust` 第五参(§7.10.14,零行为差);:1122-1123 战末导出两行删除(:1118-1121 bonus_delta 汇入保留——那是 N6 留编排器的运行态,不是计数器) -- [ ] 孤立验证:单场编排 rig begin_battle→request_dig 一次→`run_ledger.adventure_counters` 立即可见写入(无战末时点依赖) - -### T4 round 泛化+宿主清零确认(0.25d) - -**取用**:T2 的 round_start 特判、T1 的宿主成员。**产出**:三清零点在位(轮始一处+宿主 new 两处)。 - -- [ ] 确认轮始清零唯一入口=引擎 dispatch 特判(T2 已改);编排器侧零新增清零代码 -- [ ] 确认 battle/level 桶零显式清零代码(宿主 new 天然空);全仓 grep `_reset_on_round_start`/`_adventure_counter_ids`/`_reset_tree_limited_counters` 零命中 -- [ ] 孤立验证:round 桶写非零→dispatch("round_start")→整桶空;battle 前缀键同一 dispatch 下不动 - -### T5 前缀校验双落点+引用闭合(0.5d) - -**取用**:T2 的 `bucket_of` 前缀规则。**产出**:加载期前缀致命通道+读点无声明致命通道(V9 两侧)。 - -- [ ] 新增静态判定函数 `static func counter_id_legal(counter_id: String) -> bool`(名字锁定;判据见提案 §3.3 与 §12 裁点②):`round_`/`lvl_`/`adv_` 前缀=true;`meta_` 前缀=false(引擎不接存档级);其余=true(无前缀落 battle——「其余未知前缀也非法」在语法上不可判定:`feats.tres` 现有 14 枚 id 全含下划线,除三枚已带 `round_` 前缀外首段全是普通词(`pain_`/`geo_`/`helm_`…),封闭前缀词表会把它们全部判成违例,且自造词表=第二事实源红线)。自造新前缀静默落 battle 的残余风险由下条引用闭合校验(拦写读不一致)与 V10 扫描承接,不再单靠人工评审 -- [ ] **引用闭合校验**落 `config_db_cross_validator.gd`(既有跨表校验面,非单行校验):三源装载完成后收集声明集=各行 `do.counter_id` ∪ 树合成行 `do.counter_id`;再遍历全部读点(`when` 内 `fact: counter` 的 `id`、`do.value_counter`、`counter_spend` 的 `counter_id`),读点 id 不在声明集→errs 追加 `{"category": "enum", ...}` 违例→加载致命。判据只做成员判定,禁在其中再写前缀规则(契约 6)。两判据互补且不可互相替代:`meta_`/自造前缀由 `counter_id_legal` 拦,写点与读点拼错不一致由本条拦(现役 `feats.tres` 的 `:29`/`:39` 与 `:492`/`:501` 就是成对同名形态,改一半即中招) -- [ ] `validate_trigger_row` 增分支:`do` 含 `counter_id` 时校验,非法→errs 追加 `{"category": "enum", ...}` 违例 -- [ ] `_push_trigger` 增 assert:`do` 含 `counter_id` 时同规则 assert(树合成行路径,写错调试期致命;assert 消息以 `[效果引擎]` 前缀起头,供孤立验证扫描) -- [ ] 孤立验证(V9 assert 侧):`--headless --script` 最小驱动**直调 `_push_trigger`** 塞一条 `"counter_id": "meta_probe"` 行——`rebuild` 只认固定规则键,坏前缀合成行无法经 `rebuild` 从外部注入,故注入点必须是 `_push_trigger`;输出扫到 `[效果引擎]` assert 签名=拦截在位(debug 通道;assert 不改退出码,判据=输出签名扫描) -- [ ] 新建 `game/tests/unit/data_config/counter_prefix_fatal_test.gd`:copy_tables 夹具两断言——①向 feats.tres 注入 `"counter_id": "meta_probe"` 行→`load_tables` 必须拒绝;②把某行 `when` 内 `fact: counter` 的读点 id 改成表内无声明的 `"pain_layer"`(比 `pain_layers` 少一个 s)→`load_tables` 必须拒绝。任一条违规放行即 quit(2)(reward_dangling_treasure_test.gd 同构,退出码协议同款) -- [ ] `tests/run_all.gd` manifest 登记:`{"path": "res://tests/unit/data_config/counter_prefix_fatal_test.gd", "expect": 1, "negative": true}` - -### T6 数据行与合成行改名(0.25d) - -**取用**:契约 7 的 4 枚新 id。**产出**:16 枚 id 全部合规(前缀即归属)。 - -- [ ] `feats.tres`:**写点与读点成对改名**——`"twin_digs"`→`"adv_twin_digs"`(写 :29/读 `when.id` :39);`"instinct_atk"`→`"round_instinct_atk"`(写 :492/读 `value_counter` :501);`pain_layers` 各行删 `"domain": "adventure"` 键(:375-377/:407 邻近/:533-535/:626-628——归 battle,N4);`twin_digs` 行删 domain 键、`insurance_used` 行删 `domain: battle` 键(:875-877);全部 `reset_at` 键删除(:209-212/:490-494/:514-518/:719-723) -- [ ] `effect_engine.gd` 合成行(:136-155):`tree_sense_sharp_used`→`lvl_tree_sense_sharp_used`、`tree_sense_guard_used`→`lvl_tree_sense_guard_used`(when id 与 counter_id 共六处字面:锋/守各 when 两行+do counter_id 一行);**删除 :145/:155 两处 `"domain": "adventure"`**(随 DO_KEYS 删键,否则合成行自带出域键);:116-122 注释内「domain=adventure」叙述同步改前缀口径 -- [ ] `tree_rules_v11_test.gd` 夹具行(:33/:39)随合成行同源改 id + **删两处 `"domain": "adventure"`**——该夹具经 `validate_trigger_row` 校验,`DO_KEYS` 删键后不删此处即当场转红 -- [ ] 过期注释清扫(§3 清单逐处):`effect_engine.gd:42/:70-71/:118-120`、`grant_segment.gd:307`、`run_ledger.gd:7-8/:12`、`level_runner.gd:630` -- [ ] 全仓 grep 确认零 `domain`/`reset_at` 键残留(feats.tres+引擎合成行+测试夹具三处都算);`pain_layers`/`geo_types` 等 9 枚无前缀 id 零改名(前缀判据只禁 `meta_`,其余落 battle 即归属——判据理由与残余风险的承接面见 T5 与 §12 裁点②;14 枚去三枚已带 `round_` 前缀、再去本批改名的 `twin_digs`/`instinct_atk` 两枚,落地后无前缀者恰为 9 枚) - -### T7 验收断言+旧测试迁移+变异验证+同种子复放比对(1.25–1.75d) - -**取用**:T1–T6 全部产物;§9 验证闸清单(V1–V14 断言内容以本卡为唯一规格)。**产出**:V1–V13 全绿+变异验证记录表+三组复放判读记录(承载提案 §7.10.12 的 G1 已知差异面条目)。 - -- [ ] **新增单测断言**(套件内新增,断言尾缀〔无状态化 Vn〕):V2/V3/V7/V13 落 `feat_vouchers_test.gd`(V16 键名 `pain_layers:3, twin_digs:5`→`adv_twin_digs:5` 等活键改写;V25 全组保绿不改断言内容;新增 H1:bp_legacy 同时注入 `"tree_sense_sharp_used": 2` 与 `"pain_layers": 3` 两枚旧键,resume 受理零崩溃、旧键留桶成死键——`pain_layers` 旧键即契约 8 的续玩差异面);V9 落 `counter_prefix_fatal_test.gd`(T5 两断言) -- [ ] **新增冒烟断言段**(`smoke_all.gd` 树规则段近旁;每条夹具的 enc 键写死,不留给实现期自由发挥):V1(夹具=同一 `RunLedger` 下两次 `begin_battle`,**两 enc 均带 `"feats": ["twin_pick"]`**——不带则 `adv_twin_digs` 无订阅行,断言空转;第 1 战 `orch1.action_economy.request_dig(0, false)` 一次无返还+桶值 1,第 2 战一次返还成立+桶值 2);V4/V5(夹具=两编排器 enc 均带 `"tree_rules": ["sense_sharp", "sense_guard"]` 且 `"level_counters"` 传同一字典引用:第 1 战两次 `_fx.dispatch(counters_ctx, "mine_hit", {})` 命中桶值 2,第 2 战同 dispatch 返回空且桶值不动;新 LevelRunner 新桶为空);V6(第 1 战经 `_judge_seal` 置 `insurance_used=1`,第 2 战读 0);V8(round 桶直写非零→`orch._emit_round_start()`→全零,battle 前缀键不动) -- [ ] **旧断言迁移/摘除**(F2——同批同轮):`effect_words_t1_test.gd` ⑥(:77-94 export/seed 往返)改桶语义断言(共享 adventure 桶字典往返)、⑦(:96-124 reset_at/spend)重写(round 桶轮始清空语义+静态 spend);`smoke_all.gd` `:6076-6083`(counter_add+export/seed 链)改共享桶形态、`:6124-6128`(`_reset_tree_limited_counters` 直呼)删除;`:1419-1602` 裸引擎段 53 处 dispatch+8 处写口改 ctx 形态(逐行扫尽,rig 顶自建 ctx 或取 `orch.counters_ctx`);`tree_rules_v11_test.gd:29-39` 字面随 T6 新 id;`settle_segments_test.gd:32-33` 样本 id `dig_combo`→`geo_types`+ctx 形态;`treasure_effects_test.gd:34/:45/:53-56` dispatch 加 ctx;各 rig enc `"adventure_counters": {}` 死键删除(编排器只读 `enc["ledger"]`,:372 实证) -- [ ] **静态扫描 S 段**(`static_scan.sh` 新增 S11):规则=`counters_export`/`counters_seed`/`counters_merge_export`/`counters_seed_snapshot`/`_reset_tree_limited_counters` 零命中+带引号旧 id 字面 `"tree_sense_sharp_used"`/`"tree_sense_guard_used"`/`"twin_digs"`/`"instinct_atk"` 零命中(带引号匹配防新名误伤)。**扫描面必须自带扩面**:现役 `:20-24` 的扫描路径单点只有 `game/core` 与 `game/presentation`、`scan_files` 只数 `.gd`,而改名与旧字面同时存在于 `feats.tres`、`game/tests/`、`game/smoke/` 三处——本段单独声明扫 `game/**/*.gd` 与 `game/data/tables/*.tres`,并沿用 `require_scan_face` 同规做扫描面非空自检(空面判红,防静默空转);`run_all_gates.sh` 域内已有 static_scan,无闸件清单改动 -- [ ] **变异验证**(§9 变异表 7 行逐条:注入→最窄闸见红→`git checkout -- <文件>` 还原→复跑回绿→记录) -- [ ] **批内同种子复放比对**(V12):批后码按 T0 的同一命令行重跑三组 40 局(STATE=post,落 `sim-data/v12_post_*_.jsonl`),再用 `tools/parity_compare.py` 三组各判读一次——off 组 `--mode parity` 要求 20 局整条记录逐位相等;formed 组与 rules 组 `--mode input-parity` 要求输入面八字段(`policy`/`seed`/`atk_pct`/`hp_pct`/`route`/`attune`/`equipped`/`feat_mode`)与顶层字段集恒等、种子集与局数一致;输出面差异打差异表、`levels_cleared` 合计与直方图作报告行(formed 组预期不降、rules 组预期不升;10 局无统计功效,**方向不作判红依据**)。采集命令与分组(normal 档、route=min、attune/shop 显式 off,逐字与 T0 准备阶段一致): - - ```bash - mc () { "$GODOT" --headless --path "$(cygpath -m "$PWD/game")" \ - --script res://smoke/adventure_monte_carlo.gd -- \ - "$1" "$2" normal min off off "$3" "$4" 2>&1 | grep '^RUNSUM ' > "$5"; } - mc 20 81000 off "" sim-data/v12_post_off_n20.jsonl - mc 10 81000 formed "" sim-data/v12_post_formed_n10.jsonl - mc 10 81000 rules "sense_sharp,sense_guard" sim-data/v12_post_rules-sense_n10.jsonl - ``` - - 判红后的归因顺序(先排除环境再查码):在基线码上重放 5 局对哈希——一致=代码漂移(L3),不一致=环境漂移(console exe/导入缓存/种子面),按 process-conventions 环境自救清单处理后再判。逐位差异明细与三组判读结论记实现报告;40 局合计约 1.5 分钟(准备阶段实测 normal 档单局 1.8 秒),禁顺手加档 -- [ ] 里程碑步出口:`tools/run_all_gates.sh --code`(代码域闸全绿);波内修复只做出红最小单元的最窄确认 - -### T8 产出物落位卡(0.25d) - -**取用**:T0–T7 全部记录。**产出**:`reports/` 三份齐+06 状态就绪。 - -- [ ] 实现报告 `reports/iter-实现报告-<日期>.md`:各 T 卡状态+变异验证记录表(注入点 file:line/跑的闸/红输出摘要/还原结论)+三组复放判读记录(基线与复放六个文件的 sha256、T0 首提交 SHA、逐位差异明细、`levels_cleared` 直方图)+实机目检总清单(V14 登记) -- [ ] 代拍板追认单 `reports/iter-代拍板-<日期>.md`(§11 白名单内微决策逐条备案) -- [ ] 反哺点清单 `reports/iter-反哺点-<日期>.md`:§6 同步面逐条落点(architecture.md 三处改写文案与依据、tests/README 套件数、07 目检入册项、**提案三处口径订正(§7.10.3/§7.10.12/§7.7,依 §12 裁决以本卡为准)**、`sim-data/README.md` 批次例外登记) -- [ ] 轻闸全绿后合并前自查:`game/` 与 `tools/` 改动全在案、`design/` 与根规则文件零触碰(`git diff --stat` 核对) - -## 9. 验证闸(逐需求点验收清单) - -**闸口径**:批末=代码域闸全绿(冒烟+单元+探针+渲染/静态,`tools/run_all_gates.sh --code`)+批内同种子复放比对(V12,批后 40 局,二档上限内)。里程碑步(波/T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试/工具先行孤立验证再并入全套。本批无数值改动,三处预期行为差异(契约 1)由 V12 三组判读与 V1/V4/V5 确定性断言共同承载——方向性结论只由后者下,V12 只负责「没改坏」。 - -**逐需求点清单**(断言尾缀〔无状态化 Vn〕;「测什么/怎么测/谁验」三问逐条可答): - -| # | 需求点 | 测什么 | 怎么测(注入粒度) | 落点 | 谁验 | -|---|---|---|---|---|---| -| V1 | adventure 桶跨战持久(`run_ledger.gd:42` 缺陷消解回归钉面) | 第 1 战写入第 2 战可读、读写走真实事件面 | 夹具=同一 `RunLedger` 下两次 `begin_battle`、两 enc 均带 `"feats": ["twin_pick"]`:第 1 战 `orch1.action_economy.request_dig(0, false)`(无返还,`adv_twin_digs`=1)→第 2 战一次挖返还成立+桶值 2 | 冒烟新段 | 自动 | -| V2 | adventure 桶新冒险置空 | `start_adventure` 后桶空 | `start_adventure(301,...)` 后 `run_ledger.adventure_counters` 为空 | `feat_vouchers_test.gd` | 自动 | -| V3 | adventure 桶随断点往返 | 快照/回填逐位相等 | 写桶→`_on_level_finished`→`breakpoint_snapshot`→`resume_adventure`→逐键比对(键随新 id) | `feat_vouchers_test.gd`(V16 改写) | 自动 | -| V4 | level 桶同关跨战保持、进关清零 | 共享桶第 2 战保值;新 LevelRunner 新桶空 | 两编排器 enc["level_counters"] 同引用:第 2 战读 `lvl_tree_sense_*` 保持;再 new LevelRunner 断言 `level_counters` 空 | 冒烟新段 | 自动 | -| V5 | tree_sense 每关限 2 次(削弱正面确认) | 第 1 战用满→第 2 战 lt 2 闸关零命中 | 夹具=V4 同款共享 `level_counters` 引用、两 enc 均带 `"tree_rules": ["sense_sharp", "sense_guard"]`:第 1 战两次 dispatch mine_hit 命中(桶值 2)→第 2 战同 dispatch 返回空且桶值不动 | 冒烟新段 | 自动 | -| V6 | battle 桶随宿主销毁 | 第 2 战读 `insurance_used`==0 | 第 1 战 `_judge_seal` 置 1→新编排器 begin_battle 后读 0 | 冒烟新段 | 自动 | -| V7 | 完美保险每战限次一次(卡② V25 迁移保绿) | V25 全组断言原样绿 | 沿用 V25 注入口径零改写——双账同点双记不改面(契约 5) | `feat_vouchers_test.gd:130-188` | 自动 | -| V8 | round 桶轮始清空 | 轮始后 round 桶全零、他桶不动 | round 桶直写非零→`orch._emit_round_start()`→全零;`fx_counters_battle` 内键不动 | 冒烟新段 | 自动 | -| V9 | counter_id 非法前缀加载致命(.tres 行+树合成行双落点)+读点无声明加载致命(引用闭合) | 坏前缀行 load_tables 拒绝;合成行 assert 触发有据;读点 id 不在声明集 load_tables 拒绝 | 夹具①注入 `"counter_id": "meta_probe"`→load_tables false;夹具②把某 `when` 读点 id 改成 `"pain_layer"`(无声明)→load_tables false;assert 侧=T5 孤立验证(**直调 `_push_trigger`** 塞坏前缀行,输出扫 `[效果引擎]` assert 签名——`rebuild` 不认外部键,经它注入不可执行)+变异表第 4/5 行证明拦截 | `counter_prefix_fatal_test.gd`(expect 1, negative)+T5 孤立验证 | 自动 | -| V10 | 旧件零残留 | 五符号+四带引号旧 id 字面在 `game/**/*.gd` 与 `game/data/tables/*.tres` 零命中(面含测试与 smoke,不只 core) | static_scan 新增 S11 段(扫描面自带扩面+非空自检,规则见 T7) | `static_scan.sh` | 自动 | -| V11 | 旧断言同批摘除 | 冒烟/单测无旧件断言残留 | V10 扫描面覆盖测试文件+F2 清单逐项核对(`effect_words_t1` ⑥⑦/`smoke :6076-6083`/`:6124-6128`/`:1419-1602`) | 冒烟+单测迁移轮 | 自动+实现报告核对表 | -| V12 | 批内同种子复放三组判读 | off 组整条记录逐位相等;formed 组/rules 组输入面八字段与顶层字段集恒等、种子集与局数一致、零崩溃;输出面差异与 `levels_cleared` 方向只记报告 | T0 留盘基线(三组 40 局,哈希在册)vs 批后同命令同种子复放 40 局;`tools/parity_compare.py` 三组各跑一次(判据与命令见 T7) | 复放比对器+实现报告判读记录 | 自动+人工判读 | -| V13 | 旧档断点加载不崩 | 旧键 resume 受理零崩溃 | bp_legacy 同时注入 `"tree_sense_sharp_used": 2` 与 `"pain_layers": 3`→`resume_adventure` 受理、旧键留桶成死键 | `feat_vouchers_test.gd`(V16 同构) | 自动 | -| V14 | 天赋树锋/守削弱玩家可感知(登记不阻塞) | 每关第 3 次起无减免/无返还 | 用户实战目检:同关第 3 次踩雷不再减半、第 3 次标错不再返 AP | 实机目检总清单+07 入册(反哺点) | 用户目检 | - -**变异验证必做**(无变异红记录只写「已实现,拦截能力未证」): - -| 断言 | 注入形态 | 跑的最窄闸 | 期望 | -|---|---|---|---| -| V1 | T1 挂载行改 `counters_ctx.adventure_bucket = {}`(丢共享引用——复刻副本不同步缺陷类) | 跑 `smoke_all.gd` 单脚本,核对 V1 断言红 | V1 红 | -| V5 | V4/V5 两编排器改传各自新建 level 字典(复刻 :838-841 旧形态跨战不共享) | 跑 `smoke_all.gd` 单脚本,核对 V5 断言红 | V5 红 | -| V9(.tres 侧) | 注释 `validate_trigger_row` 前缀校验分支 | `counter_prefix_fatal_test.gd` 单跑 | 套件转「违规放行」态判红 | -| V9(合成行侧) | 注释 `_push_trigger` 内前缀 assert 行 | T5 孤立验证驱动单跑(输出签名扫描) | assert 签名消失=拦截失效判红 | -| V9(引用闭合侧) | 注释 `config_db_cross_validator.gd` 的闭合校验调用行 | `counter_prefix_fatal_test.gd` 单跑 | 夹具②(读点无声明)违规放行=拦截失效判红 | -| V10 | 任一源文件临时写回一处 `"counters_export"` 引用 | `static_scan.sh` 单跑 S11 段 | 扫描红 | -| V12(采集器侧) | 还原 T0 首提交那一行(`Array(…)` 包裹去掉) | T7 复放 rules 组判读 | rules 组与 off 组逐位相同=分组空转,被 L3「采集器补丁缺位」条款捕获 | - -**测试方式两分法**:V1–V13 全部=调试接口直改/直调核心层(共享字典注入、`request_dig`/`_judge_seal`/`_emit_round_start` 核心写口直调),不经 UI;V14=用户目检(登记不阻塞,验收时间用户自定)。 - -## 10. 异常分级 - -- **L1 自救**:编译错/笔误级红;孤立验证失败(新类/新函数首跑);复放脚本参数错重跑。 -- **L2 记录继续**:V12 的 formed/rules 两组输出面差异面过大(半数以上字段位移)——属轮数一变后的 RNG 级联放大,如实记录不判红;负面套件在 release 模式 assert 剥离致假绿——换 debug 通道验证并记录(配置问题非代码缺陷)。 -- **L3 停机呈报**:V12 的 off 组出现任何逐位差异,或 formed/rules 两组输入面八字段/字段集/种子集/局数任一不一致(确定性破约);rules 组复放结果与 off 组逐位相同(采集器补丁缺位,分组空转、数据不可信);V7/V25 任何一条红(契约 5 破);V13 崩溃;`pain_layers` 单战「攒层→附加→清零」行为漂移(契约 8 破);写口语义与现役不一致导致 V1–V8 连带红且无法归因单点。 -- 环境故障(worktree 缓存/资源导入/console exe)按 process-conventions 异常分级自救清单处理。 - -## 11. 代拍板白名单(超清单必呈报) - -1. 新测试函数/夹具变量命名、断言消息文案(编号尾缀〔无状态化 Vn〕已锁)。 -2. 冒烟新段的段落插入位置与段名(须紧邻现役树规则段)。 -3. 静态 `counter_add`/`counter_spend`/`bucket_of` 内部语句序(签名与语义已锁,实现体自由)。 -4. `feats.tres` 行内键序调整(键集与值已锁)。 -5. `effect_engine.gd` 合成行注释的措辞更新(口径已锁:前缀表述)。 -6. 负面套件内诊断文案措辞(退出码协议已锁)。 -7. `tools/parity_compare.py` 的内部实现与输出排版(两判据模式、`--expect`、退出码 0/1/2 与「字段集从基线推导」四条已锁)。 -8. 复放文件名里的码态后缀取值与差异表行数(三组名、种子面、留盘位置已锁)。 - -## 12. 待裁点 - -**零待裁点,开工门=U0。** - -本卡全部设计定值承自提案 §7(N1–N6)、§7.7(零采集)、§7.10(缺口闭合),均为「已生效裁定+硬纪律」推导所得并写明依据;其中以下各项带「可否决」标注(提案 §7.9/§7.10.14 同口径),用户审卡时可单独推翻、推翻即回改卡:§7.9 五条(立项判据载体/domain+reset_at 删键/`adventure_counters` 容器名不改/旧档不迁移/两编译名单删除)与 B6(dig_combo 死路删除)。卡片成立还需 grilling 复核通过(零待裁点+验收三问逐条可答已自查,见下)。 - -**owner 已裁六项(对抗复核轮 2026-10-20,已并入正文对应节,非待裁点)**: - -| # | 裁决 | 落点 | 判据 | -|---|---|---|---| -| ① | 复放基线改批内重采(三组 40 局,二档上限内),`sim-data/` 纪律③⑦开批次例外 | §1.6/契约 10/T0/T7/V12 | 现行锚 24 字段面与现采 33 字段面不同构、无 `feat_mode` 分组面,且 `sim-data/` 不入 git 致批 worktree 内根本没有该文件——「锚新鲜度核对」一步必红,原方案不可执行 | -| ② | 前缀判据采「只禁 `meta_`+其余落 battle」的松版,另加装载期引用闭合校验 | §1.5/契约 6/T5/V9 | `feats.tres` 现有 14 枚 id 全含下划线、首段除三枚 `round_` 外全是普通词,严版误伤全部既有 battle id;封闭前缀词表=第二事实源(2026-10-19 registry 注销裁定同类);实测风险形态是写读成对字面改一半,闭合校验正面拦截 | -| ③ | 改名与删键面扩到读点、合成行、测试夹具与过期注释 | T6/§7 文件结构 | `:39`/`:501` 读点、`effect_engine.gd:145/:155` 与 `tree_rules_v11_test.gd:33/:39` 的 `domain` 残留、七处注释——原卡遗漏,其中夹具残留会当场转红 | -| ④ | `pain_layers` 措辞改为「单战零变更+旧档续玩不再跨战」,列第三处预期差异 | 契约 1/8/V13 | 断点回灌路径(`adventure_runner.gd:206-208`→`:1033`)使旧档续玩可跨战携带该键,改后不再携带——属缺陷消解,不得写成「零语义变化」 | -| ⑤ | 验收夹具写死到 enc 键字面;V9 assert 侧注入点改直调 `_push_trigger` | §9 V1/V5/V9/T7 | `rebuild` 只认固定规则键,经它注入坏前缀合成行不可执行;V1/V5 不带 `"feats"`/`"tree_rules"` 则订阅行为空、断言空转 | -| ⑥ | 采集器 `rules` 注入类型缺陷修复入本批(T0 首提交),不单独开非迭代批 | T0/§7 文件结构/V12 | 一行测试工具修复在本批末的代码域闸里一起验,省一次全量闸;不修则 rules 组恒假绿,V12 削弱面失去复放承载 | - ---- - -## 附:任务卡自审五查记录(2026-10-20 成文自检) - -**grilling 复核轮**:成文后经独立会话对抗复核(新会话视角、不带写卡人假设),五项回炉点已全落——①行号群订正(成员块 :83-88/:84-87、`counters_seed` :255、`EffectEngine.new` :271、合成行 :136-155、注释 :137、rebuild :1610、裸引擎段实数 53 处、合成行字面六处);②V12 复放基线的取数面与判据(现落定为批内三组 40 局,见 §12 裁点①);③V9 assert 侧补孤立验证与变异行;④T5 判定函数名落定 `counter_id_legal`;⑤估时头对齐 T 表加总+超盒切分预案。复核结论「定点回炉后可交用户审」已执行。 - -1. **规格覆盖**:完成定义 1–8 ↔ T 卡映射——1→T2;2→T1;3→T2/T3;4→T1;5→T5;6→T7(V12);7→T3;8→T7(V13)。验收 V1–V14 逐条有落点。✓ -2. **步骤扫描**:各步一动作一核查结果;实现体未写(签名+断言已锁);无「TBD/酌情」句式。✓ -3. **类型一致性**:`EffectContext` 字段名、编排器/LevelRunner 成员名、enc 键名、静态函数签名在 T1/T2/T3/T7 引用处逐字一致(契约 7 锁定)。✓ -4. **审查焦点**:规格暗示的失败模式对照——确定性漂移(V12 off 组逐位判据+判红先归因环境再归因码)、引用切断(契约 3+V1 变异)、限次失效回退(V5 变异)、加载致命旁路(V9 三侧变异:`.tres`/合成行/引用闭合)、死路复活(V10)、复放分组空转(rules 组与 off 组同形即 L3,配采集器侧变异行)——均有承载;「同轮 dispatch 内 round 桶清空与订阅行命中并存」的时序语义由 V8+现役特判位置保持承载。✓ -5. **篇幅比例**:本卡以签名/断言/落点为主,无函数体代码块。✓ diff --git a/roadmap.md b/roadmap.md index 86c9f7d7..12e50979 100644 --- a/roadmap.md +++ b/roadmap.md @@ -5,8 +5,8 @@ ## 当前位(只回答「现在该做什么」;三行内随批次换代,禁止在此扩写成状态快照) - **阶段**:M3——Alpha 版本的完整实现(2026-10-09 立规:未明令宣布完成前停留 M3,迭代只排 M3 需求,M4 不排期;根目录 stage.txt 为旧阶段开关仅存档)。 -- **迭代位**:迭代 1–31 全部已完成或已终止;**迭代 32 待开工**(卡①代码注释禁用词清扫批+卡②效果引擎无状态化批,2026-10-20 编入,执行序①→②)。 -- **下一步**:迭代 32 开工令(U0)归用户发。其余候选在待办清单状态列——营地交互重做五卡(已写卡待编迭代)、冒险前资源配比预设(备选)、迭代 30 原卡②③(待美术/设计定稿后重新立卡)、玩家面残留禁字清扫(待写卡)。 +- **迭代位**:迭代 1–32 全部已完成或已终止;迭代 33 起未编排——候选为待编池(见下一步行),编入哪一迭代由用户经迭代编排段发令。 +- **下一步**:编排下一迭代(iter-plan)从待编池点名——营地交互重做五卡(已写卡待编排)、冒险前资源配比预设(冻结备选)、迭代 30 原卡②③(待美术/设计定稿后重新立卡)、玩家面残留禁字清扫(待写卡)、结算明细日志行序重锚(2026-10-21 授权发起、时点另定)。 ## 里程碑时间线 @@ -65,7 +65,7 @@ | 迭代 29 | 已完成(2026-10-16) | 已退役(git 历史可考) | 2026-10-16 | — | 已退役(git 历史可考) | | 迭代 30 | 已完成(2026-10-17) | 已退役(git 历史可考) | 2026-10-16 | — | 已退役(git 历史可考) | | 迭代 31 | 已完成(2026-10-19) | 已退役(git 历史可考) | 2026-10-18 | ≈1.5 周 | 已退役(git 历史可考) | -| 迭代 32 | 待开工 | reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md、reports/需求卡片-效果引擎无状态化批-2026-10-20.md | 2026-10-20 | ≈1.75 周 | — | +| 迭代 32 | 已完成(2026-10-21) | 已退役(git 历史可考) | 2026-10-20 | ≈1.75 周 | 已退役(git 历史可考) | - 历史行的「—」= 该列事实不可考:迭代 1~8 早于需求卡片制;编排时点与预计周期不再回溯,细节查 git 提交史。 - 「已退役(git 历史可考)」= 需求卡片或实现报告曾存在,已按「证据只留最新」退役;已完成迭代的实现报告列只填 reports/ 现存路径或本保留字,不填「—」。 diff --git a/待办清单.md b/待办清单.md index 3a363594..ef57a806 100644 --- a/待办清单.md +++ b/待办清单.md @@ -641,19 +641,6 @@ --- -#### 计数器寿命域未统一(2026-10-18 登记,来源=会话提及,设计面=文档轨) - -**现状**:原「寿命域统一口径」方案 2026-10-19 作废,改走效果引擎无状态化重构(提案 §8)。关联文档: -- 设计定稿:design/research/提案-效果引擎无状态化-2026-10-19.md(v1.2,2026-10-20 §7.10 闭合) -- 需求卡片:reports/需求卡片-效果引擎无状态化批-2026-10-20.md - -**证据面缺口(迭代 31 卡② 移交)**:`domain=battle` 每战清零与 `domain=adventure` 跨战持久这一对判据,现无法由单元测试 rig 变异证红(`feat_vouchers_test` 的变异②只钉住事件发射时机,未覆盖寿命域)。闭合此项时须在 runner/MC 面补一次「adventure 域计数器跨战持久 vs battle 域清零」的对照读数,或在文档批确认该判据只由代码注释与装载面约束、不设机检。 - -**归属**:architecture.md 与 game/core/effect_engine.gd(待立独立批) - -**状态**:待裁决+文档设计已闭合+待写卡+已写卡+已编迭代 32 - ---- #### 2026-10-19 定名传导遗留二项(2026-10-19 登记,来源=会话提及,设计面=文档轨) @@ -689,27 +676,6 @@ --- -#### 代码注释禁用词清扫批——退役词换代+完美封印统一+归因锚判据修正(2026-10-20 登记,来源=会话提及,设计面=工程直入) - -**现状**:2026-10-19 全量扫描 `game/`(195 个文件:.gd/.tres/.md/.json/.sh/.txt)的可复核实测读数;v1.3(2026-10-20)全量复核后口径订正=**命中行全部计入待清,显式豁免仅限 4 处**(`enemy.tres:653` 落籍留档/`level_runner.gd:832` 门票历史注记/`adventure_runner.gd:403` 正主历史修复注记/`damage_math_test.gd:36` 正主误报)——旧「信号子串过滤」实测误伤 14/17 处活注释且漏豁免 653,已废。 -**确定违规**(术语表「退役词对照」在册,落于代码注释面)=`板级` 33 处/`门票` 39 处(含移交 3 处,本批做 36)/`正主` 14 处(含误报与历史注记各 1 处,本批做 13)/`落籍` 10 处(含 `data/tables/enemy.tres:653` 带 commit 号的历史注记 1 处,不追改;本批做 9)。 -**含「雷」字面**(违反术语表「对外命名纪律」——「雷」及相关字面禁入对外命名,适用范围含 UI 文案)=`完美排雷` 21 处,其中 **3 处为玩家可见文案**:`core/battle_orchestrator.gd:925` `"完美排雷!清图奖励 ×2"`、`presentation/views/board_fx_view.gd:102` `_show_banner("完美排雷 ×2")`、`presentation/views/battle_log_view.gd:194` `"(本板完美排雷已破——归因此封印)"`(末条 `design/qa/文案审查报告-2026-10-18.md:150` 已判病句,至今未修)。 -**根因**:迭代 31 卡① 完成判据 V4 只覆盖「金币/插旗/雷格/惩罚格」四词(+旗族),`排雷`/`雷`族未入完成判据;且机检闸 `tools/doc_term_audit.py` 的 `DEFAULT_DIRS = ["design/gdd"]`,**代码注释面从未进闸**——不清根则同类残留持续复发。 -**裁定(2026-10-19 用户)**:完美排雷**全库统一**换代为「完美封印」,含代码内部注释。本裁**推翻** `需求卡片-凭证件裁削批`:108「内部开发用语按 v3.15 纪律保留」半句,该卡片条款订正归**文档轨批**,代码批照本裁执行。 -**移交(不属本批)**:`game/data/tables/shop.tres:86` display_name「奇物门票」、`game/presentation/curio_interact_controller.gd:165-166`「开一次奇物三选一」——两处属 奇物/专长 归类表述,与待办清单「2026-10-18 冒记案遗留待裁两项」第①项同源,交文档侧先定性,定后另走传导批。 -**扫描中查出的真缺陷(N7)**:`core/settlement/grant_segment.gd:300` 用 RAW 误标计数判「完美封印已破」,而 `core/battle_orchestrator.gd:1299` 的真正谓词用**有效误标**(总数 − 豁免数);且豁免累加(:314)排在 `_emit_row`(:302)之后。⇒ 装备「完美保险」时日志打印「已破」,实际加倍奖励仍发,日志与真值矛盾。2026-10-20 用户裁=并入本批修(判据改有效误标+`_emit_row` 后移至豁免循环之后+文案两态;修法 v1.2 定型——上移豁免累加需重复调用 `_fx_emit` 会重复消费限次,已核实不可行)。 - -**不做(待用户另裁)**:术语表 A 表词一族、doc-conventions 第 4 节流程动词一族、简明技术中文(STC)通用禁用词一族——三族的逐词计数与清单见卡片 §4「不做」表(本行不复制词面:待办清单正文引述禁词会自指引爆 doc_term 补充通道,判红)。 - -需求卡片:reports/需求卡片-代码注释禁用词清扫批-2026-10-20.md(v1.3)。 - -反哺写入与代拍板追认结果见本清单「迭代 32 卡① 反哺点写入」条目(2026-10-21 文档批)。 - -**归属**:game/ 代码与数据表(代码域,走独立 worktree 批;`AGENTS.md` 与 `design/` 依流水线红线本批禁碰,S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`) - -**状态**:已写卡+已编迭代 32 - ---- #### 效果引擎「系统无状态」原则缺架构文档条目(2026-10-20 登记,来源=会话提及,设计面=文档轨) @@ -733,43 +699,11 @@ --- -#### 迭代 32 卡① 反哺点写入(2026-10-21 登记,来源=批次移交,设计面=反哺点) -**现状**:清单=reports/iter32-卡①反哺点-2026-10-20.md(16 项);关联文档: -- 术语表:design/gdd/术语表.md(「退役词对照」新增「完美排雷→完美封印」行,2026-10-21 写入) -- 措辞换代八件:design/gdd/systems/战斗循环/战斗结算.md、地图战斗资源.md、战斗表现.md、design/gdd/systems/表现与支撑/HUD框架.md、design/gdd/systems/冒险循环/难度曲线与Boss.md、design/gdd/ux/battle.md、design/gdd/ux/interaction-patterns.md、design/art/art-bible.md(v3.17) -- 文档域禁词闸:tools/doc_term_audit.py(词表加「完美排雷」+扫描域扩 design/art,2026-10-21 用户裁;变异验证=注入见红、还原回绿) -- 目检入册:体验验证清单.md ㉚ 节(2026-10-21) -- 代拍板追认:reports/iter32-卡①代拍板-2026-10-20.md 七条,2026-10-21 用户全部追认 -- 遗留去向:#11 门票三处随「2026-10-18 冒记案遗留待裁两项」②另批(用户裁);#12 巢穴换代与单字「旗」清理待用户裁后另立批;#13 A 表词不纳 S11 词表(用户裁维持现状);#15 重锚见本清单「结算明细日志行序重锚批」条目;#16 状态推进已执行(见「代码注释禁用词清扫批」条目) - -**归属**:design/gdd/ 八件+design/art/art-bible.md+tools/doc_term_audit.py(文档域) - -**状态**:已写入 - ---- - -#### 迭代 32 卡② 反哺点写入(2026-10-21 登记,来源=批次移交,设计面=反哺点) - -**现状**:清单=reports/iter32-卡②反哺点-2026-10-20.md(13 项);关联文档: -- 架构三处:design/engineering/architecture/architecture.md v1.9(effect_engine 行与 battle_orchestrator 行改 ctx 形态、战斗域装配节去 export/seed 语义、架构原则补第 8 条「系统无状态」;同批订正旧事件名 flag_missed→seal_missed 两处) -- 立项条闭合:本清单「效果引擎系统无状态原则缺架构文档条目」状态已推进(v1.9 凭据在册) -- 寿命域条目:本清单「计数器寿命域未统一」整条删除归收尾批执行(其证据面缺口=V1 变异红已闭,见实现报告 §9 补漏记录) -- 提案订正三处:design/research/提案-效果引擎无状态化-2026-10-19.md v1.3(§7.7 零采集改批内重采、§7.10.3 前缀判据采松版、§7.10.12 字段面 33+三组判读,依卡片 §12 裁①②) -- 目检入册:体验验证清单.md ㉚ 节(V14 锋/守限次观感) -- 代拍板追认:reports/iter32-卡②代拍板-2026-10-20.md 七条,2026-10-21 用户全部追认 -- 偏差注记:#12 S 编号以 S12=旧件零残留为准、#13 V12 基线哈希以重采值为准(均随卡片与实现报告退役消亡) -- 采集纪律例外:sim-data/README.md 配套纪律③⑦批次例外登记(2026-10-21 写入;现行锚与读数文件未动) - -**归属**:design/engineering/architecture/+design/research/提案+sim-data/README.md+本清单(文档域) - -**状态**:已写入 - ---- #### 结算明细日志行序重锚批(2026-10-21 登记,来源=批次移交,设计面=反哺点) -**现状**:迭代 32 卡① N7 改动互换 `seal_miss`/`insurance_used` 两行日志顺序并改写豁免态 highlight(依据与预期漂移两例见 reports/iter32-卡①实现报告-2026-10-20.md「已记档差异」节);与基线数据逐项比对的 JSONL sha256 校验必红,实现批按规未发起、11 号闸落 skip。**用户 2026-10-21 裁=批准另立重锚批,发起时点另定**(重锚批只能由用户发起)。 +**现状**:迭代 32 卡① N7 改动互换 `seal_miss`/`insurance_used` 两行日志顺序并改写豁免态 highlight(豁免态=insurance_used 行先行且 highlight 置空;未豁免态=两行相对序不变但 `seal_miss` 发射时点后移——完整对照见 git 提交 d00f24a8 批内实现报告,报告已退役);`playtest_logger._on_step_row` 逐行落盘含 highlight 字段,与基线数据逐项比对的 JSONL sha256 校验必红,实现批按规未发起、11 号闸落 skip。**用户 2026-10-21 裁=批准另立重锚批,发起时点另定**(重锚批只能由用户发起)。 **归属**:`sim-data/` 锚与 `tools/parity_anchor.py`(重锚执行归用户发令批) From 259383db86ac6c131a4ff4bf7a5b431cb19fccdc Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 04:36:48 +0800 Subject: [PATCH 51/59] =?UTF-8?q?docs(=E6=94=B6=E5=B0=BE=E6=BC=8F=E6=94=B9?= =?UTF-8?q?=E8=A1=A5=E5=87=80):=20=E4=BD=93=E9=AA=8C=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E6=B8=85=E5=8D=95:142=20=E7=8E=B0=E8=A1=8C=E8=AF=AD=E4=B9=89?= =?UTF-8?q?=E5=8F=A5=E3=80=8C=E5=AE=8C=E7=BE=8E=E6=8E=92=E9=9B=B7=E3=80=8D?= =?UTF-8?q?=E2=86=92=E3=80=8C=E5=AE=8C=E7=BE=8E=E5=B0=81=E5=8D=B0=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 反哺点卡①#10 含两个动作(措辞换代+新增目检项),前批只做了后者。此行属现行正文引用旧词,非留档注记; 根流程清单不在 doc_term 扫描域(DEFAULT_DIRS=design/gdd+design/art),故闸不拦——已呈报该覆盖缺口待裁。 --- 体验验证清单.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/体验验证清单.md b/体验验证清单.md index 60ab2871..055f5e77 100644 --- a/体验验证清单.md +++ b/体验验证清单.md @@ -139,7 +139,7 @@ - **机制一句**:封印标中的正向兑付现在按同型正向 ×1.25 兑付(`settlement.tres` flag_hit_premium=125 provisional——条款3 条件二封印溢价形态 a),标空与挖格兑付不变;危险格与安全格同池结构零触碰。 - **看什么(实机目检,约 5 分钟)**:①封印标中一处危险格,结算明细的兑付数值应比改前同类行略大(增伤 50→63 / 削弱 65→81 / 急救 2→3 / GP 袋 3→4;盾牌加护与行动点 1 点量纲不变=整数粒度地板);②挖安全格与标空惩罚行数值应与改前逐位相同;③战斗结算帮助文案如有封印相关行,无自造词。 - **行为读数(改前改后 MC 锚已采,判读随出口报告顺带交付)**:η=封印标中÷封印 与 封印率 位移 ≥5pp 判「有感」;行为无效 δ 仍保留+登记「行为无感」(判式诚实性不依赖行为弹性——2026-10-04 grill Q4 裁)。 -- **红灯信号**:封印 rush 复发(首轮全封印不挖——δ 与完美排雷 ×2 叠加通胀是既有联动面:封印溢价三件套 δ↔p_perfect↔ap_per_round 同窗检算,难度曲线与Boss 调参联动表在册)。 +- **红灯信号**:封印 rush 复发(首轮全封印不挖——δ 与完美封印 ×2 叠加通胀是既有联动面:封印溢价三件套 δ↔p_perfect↔ap_per_round 同窗检算,难度曲线与Boss 调参联动表在册)。 - **结论回流**:体感 → 本条目记录;数值终值(δ 值与 ×1.5 档留后手)归调参批,不在试玩现场改数。**判式换代文本(行动经济 F1 条款3/战斗结算 验收标准/难度曲线与Boss 联动表三处修订稿)顺带呈用户人闸**——追认单随出口报告。 ### ⑬ 初始展开收窄体感(2026-10-05 初始展开收窄批顺带登记——迭代14①号卡;需求卡片 §T8 四信号组) From 4d03c3457c0369074d6a8d63f419ad239efe644f Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 04:42:51 +0800 Subject: [PATCH 52/59] =?UTF-8?q?docs(=E5=85=B3=E5=8D=A1=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E5=9B=BE=E9=87=8D=E6=9E=84):=20=E5=85=B3=E5=8D=A1=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E5=9B=BE=E7=94=9F=E6=88=90=20v1.0=20=E8=90=BD?= =?UTF-8?q?=E5=AE=9A=EF=BC=8B=E5=85=B3=E5=8D=A1=E8=8A=82=E7=82=B9=E5=9C=B0?= =?UTF-8?q?=E5=9B=BE=20v2.0=20=E5=A4=9A=E7=BB=88=E7=82=B9=E6=8D=A2?= =?UTF-8?q?=E4=BB=A3=E2=80=94=E2=80=94=E4=BA=A7=E5=87=BA=E8=A7=84=E6=A0=BC?= =?UTF-8?q?=E5=94=AF=E4=B8=80=E9=99=88=E8=BF=B0=E5=A4=84/=E4=BA=94?= =?UTF-8?q?=E6=97=8B=E9=92=AE=E5=8F=82=E6=95=B0=E6=A1=A3/=E6=B7=B1?= =?UTF-8?q?=E5=BA=A6=E5=B8=A6=E9=85=8D=E6=B1=A0/=E6=AF=8F=E7=BB=88?= =?UTF-8?q?=E7=82=B9=E5=89=8D=E4=B8=80=E5=BA=97=EF=BC=8C=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E5=9F=9F=E9=97=B8=E5=85=A8=E7=BB=BF=EF=BC=88=E5=9B=9E=E6=89=A7?= =?UTF-8?q?=20domain=3Ddocs=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/gdd/02-系统清单.md | 1 + design/gdd/08-Alpha版本标准.md | 4 +- design/gdd/systems/冒险循环/关卡节点图生成.md | 119 ++++++++++++++++++ design/gdd/systems/冒险循环/关卡节点地图.md | 33 ++--- design/gdd/systems/冒险循环/冒险结构.md | 4 +- design/gdd/systems/战斗循环/敌人系统.md | 6 +- design/gdd/ux/level-map.md | 2 +- 待办清单.md | 12 +- 8 files changed, 152 insertions(+), 29 deletions(-) create mode 100644 design/gdd/systems/冒险循环/关卡节点图生成.md diff --git a/design/gdd/02-系统清单.md b/design/gdd/02-系统清单.md index 7c669554..598fa9ab 100644 --- a/design/gdd/02-系统清单.md +++ b/design/gdd/02-系统清单.md @@ -43,6 +43,7 @@ | 文件 | 一句话概要 | 状态 | |---|---|---| | `关卡节点地图.md` | 单关内的节点图选路与推进 | 已定稿 | +| `关卡节点图生成.md` | 一关的节点图从哪来——生成器按参数产出合法图 | 已定稿 | | `冒险结构.md` | 整局冒险的关卡序列、失败与大奖励 | 已定稿·自旧体系迁移 | | `难度曲线与Boss.md` | 难度曲线、期望值带与 Boss 设计 | 已定稿·自旧体系迁移 | | `奇物.md` | 一次冒险内各渠道给予玩家的增益总称(专长=触发器句式的机制件 / 属性值提升 / 补给=给系统资源加一笔的转换源凭证 × 三条渠道:奖励节点 / 商店 / 关底 Boss 击败) | 已实现·迭代 20 专长实装批落地(29 行=基础 27+迁入 2,流派机制退役;池结构案D 四级 104,通关兑付=专长三选一按档配比加权) | diff --git a/design/gdd/08-Alpha版本标准.md b/design/gdd/08-Alpha版本标准.md index 8e723532..3d1bc3ef 100644 --- a/design/gdd/08-Alpha版本标准.md +++ b/design/gdd/08-Alpha版本标准.md @@ -45,8 +45,8 @@ |---|---|---| | 冒险结构 | [冒险结构](systems/冒险循环/冒险结构.md) | 在役 | | 关卡节点地图 | [关卡节点地图](systems/冒险循环/关卡节点地图.md) | 在役(待重构,见下一条) | -| 关卡节点图重构(增加可选节点) | [关卡节点地图](systems/冒险循环/关卡节点地图.md) | 待做(须先做文档设计,不可直接开发) | -| 关卡节点图生成 | 旧版文档已删,随关卡节点图重构批重写 | 在役(待重构,与上一条同批) | +| 关卡节点图重构(增加可选节点) | [关卡节点地图](systems/冒险循环/关卡节点地图.md)+[关卡节点图生成](systems/冒险循环/关卡节点图生成.md) | 待做(文档设计已闭合,待写卡) | +| 关卡节点图生成 | 参数化长图:产出规格与生成参数 | 在役(v1.0 重写完成,与上一条同批实施) | | 难度曲线与 Boss | [难度曲线与Boss](systems/冒险循环/难度曲线与Boss.md) | 在役 | | 奇物 | [奇物](systems/冒险循环/奇物.md) | 在役 | diff --git a/design/gdd/systems/冒险循环/关卡节点图生成.md b/design/gdd/systems/冒险循环/关卡节点图生成.md new file mode 100644 index 00000000..b103a984 --- /dev/null +++ b/design/gdd/systems/冒险循环/关卡节点图生成.md @@ -0,0 +1,119 @@ +# 关卡节点图生成 + +> 一句话:一关的节点图从哪来——生成器按参数长出一张合法图 +> 状态:现行为 v1.0 + +## 设计目的 + +固定模板的图太小:第一关一条链零选择,第二三关网状但岔路兑付差不多,「可选节点太少」换画法解决不了。本文把图的来源换成参数化生成——图更大、岔口更多、每条路通向不同的东西,走哪条路决定打谁;规模随关卡推进生长,层高、宽度、节点数逐关递增且增幅变大。改形态=改参数不改代码。 + +## 系统范围 + +负责: + +| 负责 | 说明 | +|---|---| +| 图从哪来 | 按本关参数档长出一张节点图,交付给关卡节点地图 | +| 产出规格 | 什么算一张合法的图——产出约束的唯一陈述处 | +| 生成参数 | 五个旋钮、三套关卡参数档与生长曲线 | +| 节点类型配比 | 节点类型分布怎么掷、商店位这类摆放约束 | + +不负责: + +| 不负责 | 归谁 | +|---|---| +| 图怎么走、每类节点到达时兑付什么 | 关卡节点地图 | +| 节点上具体摆什么料(敌人行集、奖励内容) | 敌人系统、冒险结构等各 owner 文档 | +| 图的画面呈现与多终点标记 | level-map、HUD 框架 | +| 生成算法本身 | 代码——本文只给产出规格与执行边界,图怎么长出来是实现的事 | + +## 在核心循环中的位置 + + 冒险结构 ──开始关卡(关卡序号+参数档)──▶ 关卡节点图生成:长出本关的图 + ──图交付──▶ 关卡节点地图:选路推进 ──关卡结束──▶ 冒险结构 + +生成站在冒险结构与关卡节点地图之间:接「第几关、用哪套参数档」,交「一张合法图」。图一旦交付生成即退场,走图的事全归关卡节点地图。 + +## 核心规则 + +### 图的规格:什么算一张合法的图 + +合法图是一张岔路发散式道路系统:主路+支路,宽度由分叉自然长出,多终点时提前承诺归属。产出约束五条,每张产出图都必须满足: + +| 约束 | 内容 | +|---|---| +| 道路系统 | 图=主路+支路;除岔口节点(两条以上去路的节点)外每个节点恰一条去路;岔口去路 2–3 条 | +| 宽度=分叉生长 | 不摆平行层;同深度节点数由岔口自然长出(1→2→3→4……) | +| 层高=沿路步数 | 入口到终点的最长路径步数;第一关 ≥6,逐关递增且增幅变大 | +| 出口归属锁定 | 多终点时由大岔口把图分成互不连达的分支区域,各区域只通向自己的终点;每个终点前一层节点的去路集合恰含一个终点——选路=提前承诺打谁 | +| 战斗节点保底 | 奖励/恢复/商店占位后战斗节点量不被挤没(保底数进调参表) | + +结构铁律:连线只朝前进方向(无环);入口、终点都可多个(个数=参数档),每条路径恰好从一个入口出发、恰好到达一个终点。 + +执行边界(实现只须遵守这几条,怎么长图是代码的事): + +| 边界 | 内容 | +|---|---| +| 不合格产出禁止进玩法 | 产出不过产出规格即无效,无效图绝不上给玩家 | +| 无兜底图 | 不设固定兜底图——软回退一律禁止 | +| 参数无解即中止 | 参数档本身给不出合法图=配置错误,致命中止 | +| 同种子同图 | 同种子+同参数档产出同一张图;随机只经 RngService 统一流 | + +### 生成参数:五个旋钮与三套关卡参数档 + +| 旋钮 | 管什么 | +|---|---| +| 层深 | 图有多高(沿路步数) | +| 分支密度 | 岔口多少、宽度长多快 | +| 配比 | 节点类型分布(见下节) | +| 入口个数 | 图从几个点进场 | +| 出口个数 | 图通向几个终点(1=单出口;2 及以上=多出口+归属锁定) | + +每关一套参数档(L1/L2/L3),生成器只吃参数档、不认关卡号。生长曲线:层高、宽度、节点总数、路径长度逐关递增且增幅变大;决策点密度逐关递增;第一关即含岔口——第一关也要有选择。单链是分支密度取下限的合法退化形态,不作为三关参数档的取值。 + +### 节点类型配比:类型分布怎么掷、内容归谁 + +配比是生成旋钮:战斗/奖励/恢复/商店各占多少由参数档定,生成器掷出分布落在图上成为节点类型;配比只管非终点节点,终点恒为 Boss、不进配比。类型构成在图上公开呈现——看得见类型才谈得上提前规划,这是选路成为决策的前提。 + +摆放约束:每个终点前一位恰一家商店——每名玩家一局必经恰一家店。 + +内容归各 owner:战斗节点打谁=敌人系统按深度带配池;奖励/恢复/商店的兑付语义=关卡节点地图与各 owner 文档。精英、事件这类新类型进不进图、怎么进,归内容层专题;要进就走本文档修订,类型扩展与配比调整一起落。 + +## 依赖与输出 + +| 方向 | 系统 / 文档 | 接口要点 | +|---|---|---| +| 上游 | 冒险结构 | 开始关卡给出关卡序号与本关参数档 | +| 下游 | 关卡节点地图 | 图的消费方:选路、兑付、加载校验(结构规则以本文产出规格为准) | +| 协作 | 敌人系统 | 战斗节点遭遇按深度带配池,遭遇坐标=关卡序号+深度带;多终点各配 Boss 行 | +| 协作 | 难度曲线与Boss | 图规模(节点数/战斗量)进它的投放节奏账;深度带配池的难度坡归它,本文零数值 | +| 上游 | 数据配置 | 参数档数据的承载与统一读取,数值事实源=data/tables | +| 协作 | level-map | 呈现只读:图形态随参数变化,画布自适应;多终点各带 Boss 标记 | + +## 调参表 + +数值事实源=game/data/tables(定值批落表);本表只留取值域与设计意图。 + +| 参数 | 取值域 | 设计意图 | 状态 | +|---|---|---|---| +| 层深 L1 | ≥6(步) | 第一关不再是零选择短链——够长才有岔口与取舍 | 已锁下限 | +| 层深 L2/L3 | >前一关且增幅变大 | 后期关显著更长,推进感随冒险加深 | provisional | +| 岔口去路数 | 2–3 | 每次取舍在 2–3 条里选:少了没选择,多了不过脑 | 已锁 | +| 分支密度 | 待定值 | 一局遇到多少次取舍(目标量级=一局十几次,待设计验证) | provisional | +| 入口个数 | 1 起 | 多入口给「从哪进场」的第一层选择 | provisional | +| 出口个数 | 1–3 | 多终点让「走哪条=打谁」成立 | 已锁范围 | +| 配比 | 四类占比合计 1,战斗保底优先 | 攻击性/兑付/恢复的节奏配比 | provisional | +| 战斗节点保底数 | ≥ 调参值 | 成长位不挤没战斗——战斗是本作核心量 | provisional | +| 商店数 | =出口数 | 每局决战前恰一次补给,成长保底是结构事实 | 已锁 | + +## 验收标准 + +| 判据 | 内容 | +|---|---| +| 产出合格 | 任意参数档产出的图必过产出约束五条+结构铁律;任意入口出发的任意路径都恰好到达一个终点 | +| 生长递增 | L1/L2/L3 读数:最长路径步数与节点总数均逐关递增;节点总数增幅 Δ(L2→L3)>Δ(L1→L2) | +| 归属锁定 | 多出口图每个终点前一层节点的去路集合恰含一个终点;各分支区域互不连达 | +| 必经恰一店 | 任意入口→终点路径经过且恰经过一家店 | +| 可复现 | 同种子+同参数档=同一张图 | +| 无软回退 | 不存在兜底图路径;参数无解即致命中止 | +| 战斗保底 | 任意合法产出的战斗节点数 ≥ 保底数 | diff --git a/design/gdd/systems/冒险循环/关卡节点地图.md b/design/gdd/systems/冒险循环/关卡节点地图.md index 17c0136a..f0b41963 100644 --- a/design/gdd/systems/冒险循环/关卡节点地图.md +++ b/design/gdd/systems/冒险循环/关卡节点地图.md @@ -1,33 +1,34 @@ # 关卡节点地图 > 一句话:单关内的节点图选路与推进 -> 状态:已定稿 +> 状态:现行为 v2.0 ## 设计目的 -一关不是一场战斗,而是由关卡表配置的一组**节点**(本文含义:关卡内移动的步进单位,画在图上就是一个格)连成的一张**节点图**。玩家从一个入口出发,在每个路口看着几条路选一条走——这条路上有要打的仗、有开奖励的房间、有能歇脚的篝火——最后所有路线汇到关底 Boss。关卡节点地图管的就是这张图上的"走":怎么选路、走到每种节点上发生什么、Boss 分出胜负后怎么把这一关的结局交回去。 +一关不是一场战斗,而是由关卡表配置的一组**节点**(本文含义:关卡内移动的步进单位,画在图上就是一个格)连成的一张**节点图**。玩家从一个入口出发,在每个路口看着几条路选一条走——这条路上有要打的仗、有开奖励的房间、有能歇脚的篝火——最后走到关底 Boss(终点可以有多个,走哪条路决定打谁)。关卡节点地图管的就是这张图上的"走":怎么选路、走到每种节点上发生什么、Boss 分出胜负后怎么把这一关的结局交回去。 用循环的层次说:冒险是外层骨架,关卡是**中循环**,战斗是**小循环**。本文管中循环——图怎么编排、怎么走、每类节点到达时触发什么;一场战斗内部发生什么全部归小循环(战斗结算与敌人系统),本文把控制流移交给它之后就不再看里面。它是[冒险结构](冒险结构.md)(序列、大奖励、重开)与战斗循环(结算与敌人)之间的行进层。 ## 系统范围 -边界这样划:图上**有哪些节点**(具体摆什么、摆几个)是关卡表的内容,归冒险结构;本文管图**怎么走、走到每步发生什么**,以及一张关卡表行集要满足什么结构规则才算合法的图。战斗内部的一切(敌人怎么配、几只、什么技能池、踩雷负向怎么兑)归战斗循环文档(原"伏击怎么叠"随 2026-09-20 八型批伏击退役改述);本文只负责把"第几关、哪个节点"递过去。 +边界这样划:图**从哪来**(按参数长图)与**什么算合法图**(产出规格)归[关卡节点图生成](关卡节点图生成.md);图上**具体摆什么料**(敌人行集、奖励内容)归各 owner 系统;本文管图**怎么走、走到每步发生什么**,以及加载期的合法性校验动作(规则语义以关卡节点图生成的产出规格为准)。战斗内部的一切(敌人怎么配、几只、什么技能池、踩雷负向怎么兑)归战斗循环文档(原"伏击怎么叠"随 2026-09-20 八型批伏击退役改述);本文只负责把"第几关、哪个节点"递过去。 负责: | 负责 | 说明 | |---|---| -| 节点图结构规则 | 什么算一张合法的关卡节点图(唯一编号、唯一入口、唯一终点、不可回头)——结构校验的规则面 | +| 图合法性校验 | 加载期校验动作;合法图的规则语义以[关卡节点图生成](关卡节点图生成.md)的产出规格为准 | | 选路与行进 | 玩家亲手选路前进;兑付后确认、零自动推进(交互形态定稿) | | 节点兑付触发 | 行进到各类型节点时触发对应兑付:战斗移交、奖励入库、恢复请求、商店覆盖层开闭 | -| 战斗发起组装 | 组装定位信息(关卡序号 + 节点编号),移交战斗结算开战 | +| 战斗发起组装 | 组装定位信息(关卡序号 + 节点深度),移交战斗结算开战 | | 关卡收束点 | Boss 战胜利或英雄死亡时定局:先调战斗结算的关卡收束清空库存,再向冒险结构宣布关卡结束 | 不负责: | 不负责 | 归谁 | |---|---| -| 关卡序列与图上摆哪些节点(行集内容、关数) | [冒险结构](冒险结构.md) | +| 关卡序列与关数 | [冒险结构](冒险结构.md) | +| 图从哪来、节点类型构成与合法图规则 | [关卡节点图生成](关卡节点图生成.md) | | 关卡大奖励、跨战斗生命、失败重开 | [冒险结构](冒险结构.md) | | 战斗内部的一切:敌人配置、数量、技能池、踩雷负向 | [敌人系统](../战斗循环/敌人系统.md)与[战斗结算](../战斗循环/战斗结算.md) | | 同场多敌种(同一节点配多种敌人)的表结构与取值口径 | 敌人系统(战斗侧改键批) | @@ -47,7 +48,7 @@ ### 关卡的形状:分支节点图与五类节点 -一关内部是一张**有方向的节点图**:节点之间用连线(本文含义:节点之间允许前进的通道)连接,玩家沿连线从一个节点走到下一个节点。图有三条结构铁律:连线只朝前进方向(没有回头路,整张图无环);图有一个唯一的入口节点;**关底 Boss 恒为全图唯一的终点**——所有路线最终都汇到它,打赢它这一关就通了。违反任何一条的行集是配置违约,加载期拦截。 +一关内部是一张**有方向的节点图**:节点之间用连线(本文含义:节点之间允许前进的通道)连接,玩家沿连线从一个节点走到下一个节点。结构铁律的规则语义以[关卡节点图生成](关卡节点图生成.md)的产出规格为准,走图视角三句:连线只朝前进方向(没有回头路,整张图无环);每条路径恰好从一个入口出发、恰好到达一个终点;终点恒为 Boss(终点可以有多个,走哪条路决定打谁)。违反任何一条的行集是配置违约,加载期拦截。 图上只有五种节点,封闭枚举,扩类一律走文档修订: @@ -59,9 +60,9 @@ | 恢复 | 行进至此向冒险结构发治疗封顶回报;反馈呈现后回到选路 | | 商店 | 行进至此打开商店覆盖层,用 GP(战斗掉落的冒险内货币)购买属性提升;离开后兑付确认回选路;不携带战斗行。**v1.5 兑付换代(pool 模式现行)**:进店从共享池抽 3 展示、买 1 后三件全重抽(未买不保留)、货架买空=空架合法态。**v1.6(2026-10-04 P-C2+Q2 裁/MC-1)**:新增**独立刷新**——基础免费 0 次(天赋/营地侧刷新次数增益位预留)+ GP 付费刷新 ceil(20×1.8^已付费刷) provisional;重抽=共享池同源(shop_draw 同签),推翻本行旧「无独立刷新动作——重抽绑购买」口径;库存与定价归[冒险结构](冒险结构.md)共享池节 | -商店房的编排规则(2026-09-20 用户拍板):每关**恰 1 个**商店房,位置 = **关底 Boss 前一位**——哈迪斯式的"决战前最后一个补给点":买到的属性还有整段战斗可消费,错过的成长也没有第二家店可补。Boss 前一位同时是**必经位**:图拓扑收束使所有入口→Boss 的路径都穿过它,成长保底成为图结构事实而非玩家自觉。这条位置约束不由加载校验承载——图合法性六检零新增,商店房的"每关恰 1 + 必经"由冒烟断言把关。 +商店房的编排规则:**每个终点前一位恰一家店**——哈迪斯式的"决战前最后一个补给点":买到的属性还有整段战斗可消费,错过的成长也没有第二家店可补。终点前一位同时是**必经位**:每名玩家一局恰好必经一家店,成长保底是图结构事实而非玩家自觉。这条位置约束不由加载校验承载,由冒烟断言把关(摆放规则语义见[关卡节点图生成](关卡节点图生成.md)配比节)。 -每个节点在关卡内领一个**节点编号**(本文含义:关卡内不重复的序号,用来当战斗的定位地址;数据键沿用切片字段 `node_depth`)。Boss 的编号恒为全图最大——"最深处的房间是关底"这条直感由此保留。单链特例:一张每步只有一条连线的图就是一条链,此时节点编号等于它前面走过的战斗场数。第一关行集就是单链特例,切片代码零改动运行;分支图行集已落地(v1.0.1 起;图的来源与模板池随关卡节点图重构批重写,旧生成文档已删)。 +每个节点在图上有**节点深度**(本文含义:从入口沿路走过来的步数),用来当战斗的定位地址——遭遇坐标=关卡序号+节点深度,敌人表按**深度带**(深度区间)配池,寻址语义见[敌人系统](../战斗循环/敌人系统.md)。"最深处是关底"的直感由深度承载:终点恒在各路径最深处。单链(每步只有一条连线)是合法退化形态,节点深度等于它前面走过的战斗场数;三关参数档都含岔口,第一关不再是单链。图的来源见[关卡节点图生成](关卡节点图生成.md)。 呈现侧口径(2026-09-17 用户拍板):节点图的画面表达走**方块地牢观感**——节点画成地牢房间的方块、连线画成通道——但逻辑拓扑就是本文的节点图,不产生任何额外选路或探索语义。关卡画面本体即节点链进度的呈现载体(选路覆盖层的常驻形态,节点态直接读图:已过暗金 / 当前金 / 候选下一跳通道亮金 / Boss 封印黑描边(旗朱→封印紫→封印黑 #000000,2026-09-28 用户拍板现行)),不另设进度条组件;视觉规格归 [HUD 框架](../表现与支撑/HUD框架.md)。 @@ -95,7 +96,7 @@ Boss 兑付(胜利或英雄死亡)触发关卡收束点,此后不再有选 | 类型 | 兑付动作 | |---|---| -| 战斗 / Boss | 组装定位信息(关卡序号 + 节点编号),移交[战斗结算](../战斗循环/战斗结算.md)开战;战斗结果(胜负与战后生命)经战斗结果上报回流冒险结构(契约语义归[冒险结构](冒险结构.md),本文不复述) | +| 战斗 / Boss | 组装定位信息(关卡序号 + 节点深度),移交[战斗结算](../战斗循环/战斗结算.md)开战;战斗结果(胜负与战后生命)经战斗结果上报回流冒险结构(契约语义归[冒险结构](冒险结构.md),本文不复述) | | 恢复 | 向冒险结构发治疗封顶回报(载荷 = 该关恢复比例,读本关配置行);按比例回血并封顶的执行归冒险结构 | | 奖励 | 触发节点奖励兑付:提升三选一(与通关三选一共享同一令牌库——七种令牌洗牌不放回抽 3 点选一件,池耗即上限;见下节) | | 商店 | 打开商店覆盖层(pool 模式:进店抽 3〔shop_draw 封闭流恰一 scope〕+买 1 全重抽;legacy 对照模式:商品陈列读商店表);购买即时生效、经共享池写统一冒险加算区(与关卡大奖励同一笔——库存语义归[冒险结构](冒险结构.md),本文不复述);离开覆盖层即兑付确认。商店房不携带战斗行:零敌人、零棋盘、零战斗初始化 | @@ -103,7 +104,7 @@ Boss 兑付(胜利或英雄死亡)触发关卡收束点,此后不再有选 **遭遇构成的编排面**——本文对"放什么敌人"的全部职责只有三条: 1. 行进到战斗或 Boss 节点,兑付动作就是开战:本文递出定位信息,移交战斗结算。 -2. 定位信息只有两样:**关卡序号 + 节点编号**。战斗侧拿编号查表、配敌、掷数量、跑技能池、兑踩雷负向——一切战斗内部初始化归战斗循环文档(原"叠伏击"随 2026-09-20 八型批伏击退役改述),图的初始化不为战斗初始化做任何决定。 +2. 定位信息只有两样:**关卡序号 + 节点深度**。战斗侧按深度带配池查表、配敌、掷数量、跑技能池、兑踩雷负向——一切战斗内部初始化归战斗循环文档,图的初始化不为战斗初始化做任何决定。 3. 本文不预掷任何战斗数值、不读敌人数量;教学位节点同样掷骰、没有结构豁免("任何掷骰结果下都稳过"的保证是[难度曲线与Boss](难度曲线与Boss.md)的数值责任)。 第二关的"新内容 = 既有池新技能"(技能池构成已定稿入[敌人系统](../战斗循环/敌人系统.md)技能池节)投放时,改的是战斗侧行里引用的技能池内容——节点图结构原样不动,本文无需为投放留任何新结构位。 @@ -143,7 +144,7 @@ Boss 兑付(胜利或英雄死亡)触发关卡收束点,此后不再有选 3. 战斗 / Boss 节点:组装关卡序号 + 节点编号,移交战斗结算开战;战斗结束向冒险结构上报战斗结果。 4. 奖励节点:触发节点奖励兑付 = 提升三选一(与通关三选一共享令牌库);恢复节点:向冒险结构发治疗封顶回报;商店节点:打开商店覆盖层,购买即时生效,离开后兑付确认。 5. Boss 战胜利或任意战斗倒下 = 关卡收束点:先调战斗结算的关卡收束清库,再宣布关卡结束。 -6. 第一关行集 = 单链特例(图的最简形态),切片按单链运行零改动;分支图行集与图版实现已落地(v1.0.1 起)。 +6. 单链是合法退化形态;三关参数档都含岔口,第一关即有选择(图的来源见[关卡节点图生成](关卡节点图生成.md))。 ## P1 / P2 后置 @@ -156,20 +157,20 @@ Boss 兑付(胜利或英雄死亡)触发关卡收束点,此后不再有选 ## 调参表 -暂无本系统自有的参数——选路与行进无数值可调。图结构合法性(唯一编号、唯一入口、唯一终点、无环)是规则不是参数,由加载校验强制;链上节点构成归冒险结构的关卡表,战斗数值归难度曲线与Boss。 +暂无本系统自有的参数——选路与行进无数值可调。图结构合法性是规则不是参数(规则语义见[关卡节点图生成](关卡节点图生成.md)的产出规格),由加载校验强制;图的来源与节点构成归[关卡节点图生成](关卡节点图生成.md),战斗数值归难度曲线与Boss。 ## 验收标准 -- 图合法:行集通过加载校验——节点编号关卡内唯一、入口唯一、Boss 为唯一终点、连线无环、所有节点沿连线可达 Boss;违规配置加载期致命。 +- 图合法:行集通过加载校验——每条路径恰好从一个入口出发、恰好到达一个终点,终点恒为 Boss(可多个)、连线无环、任意入口出发的任意路径都到达某一个终点;违规配置加载期致命(规则语义见[关卡节点图生成](关卡节点图生成.md)产出规格)。 - 行进自主:从入口到 Boss 的每一次前进都由玩家选路发起(含关卡开始后的第一跳——关卡开始停在图上,入口节点不自动进入);不存在任何自动推进路径;倒下时行进终止。 - 兑付移交:每场开战调用携带(关卡序号 + 节点编号),与节点图上该节点位置一致;每场战斗结束恰一次战斗结果上报。 - 兑付后确认:战斗节点的继续确认挂战斗总结结算(settlement-summary.md),奖励/恢复挂兑付反馈覆盖层;到达与兑付之间无确认步。 - 恢复兑付:治疗封顶回报载荷 = 该关恢复比例(读关卡配置行);满血回复 0 是合法状态(执行语义归冒险结构)。 - 奖励兑付:奖励节点兑付恰触发一次;池空直通空态合法,现行 = 提升三选一(与通关三选一共享令牌库)取一件按件类兑付(spec:node-reward.md v2.x;兑付路由归[冒险结构](冒险结构.md)提升池节)。 -- 商店房编排:每关恰 1 个商店房、Boss 前一位必经位(所有入口→Boss 路径都穿过它)——由冒烟断言把关,图合法性校验零新增检查;商店房不携带战斗行;行进至此打开商店覆盖层、离开后兑付确认回选路。 +- 商店房编排:每个终点前一位恰一家店、每名玩家一局必经恰一家(所有入口→终点路径都穿过且恰穿过一家店)——由冒烟断言把关,图合法性校验零新增检查;商店房不携带战斗行;行进至此打开商店覆盖层、离开后兑付确认回选路。 - 收束有序且唯一:关卡清库发生在关卡结束宣布之前;每关恰宣布一次关卡结束;Boss 胜 = 通关、倒下 = 失败。 - 四件接口全款:与冒险结构登记的开始关卡、战斗结果上报、治疗封顶回报、关卡结束逐件对上,不另起平行通道。 -- 单链特例合法:单链行集(每步恰一条连线)是合法图形态;第一关按单链运行,切片零改动。 +- 单链特例合法:单链行集(每步恰一条连线)是合法退化形态;三关参数档都含岔口,第一关即有选择。 - 呈现只读:节点图结构、当前位置、可选下一节点对呈现层只读可见(读数契约归 HUD 框架)。 ## 待办 diff --git a/design/gdd/systems/冒险循环/冒险结构.md b/design/gdd/systems/冒险循环/冒险结构.md index c024aad8..890add6b 100644 --- a/design/gdd/systems/冒险循环/冒险结构.md +++ b/design/gdd/systems/冒险循环/冒险结构.md @@ -261,7 +261,7 @@ GP(显示名「GP」)是冒险内的一次性属性提升货币:战斗胜 | 参数 | 域 | 现行值 | 说明 | |---|---|---|---| -| 关卡行集(关数与节点链模板) | 关卡表逐关行 | 三关现行(逐关 templates 池 3 关 × 5,模板 0 = 回滚档;生成机制随关卡节点图重构批重写,旧生成文档已删) | 加关 = 内容批(链行 + 敌我数值 + 新元素同批);L1 回滚档模板 = 两战 → 奖励 → 两战 → 恢复 → 关底 Boss(7 节点,战斗深度 5) | +| 关卡行集(关数与图的参数档) | 关卡表逐关行 | 三关现行(图由生成器按参数档产出,见[关卡节点图生成](关卡节点图生成.md);旧模板池随实现批清数据) | 加关 = 内容批(参数档 + 敌我数值 + 新元素同批);确定性 = 固定种子+固定参数档(首局教学与存档复现的固定图由此承载,无兜底模板) | | 恢复比例 | int [0,100],逐关行 | 见 level.tres rest_heal_pct(provisional) | 恢复点回复生效上限的百分比;随上限加成同步放大;100 = 恢复点变全满泉,0 = 死节点 | | 上限提升 | int [0,999],冒险表逐件列 | adventure_table bonus_attack_flat / bonus_max_hp_flat / bonus_armor_flat(provisional) | 三选一属性件各自兑付值;值锚与上调约束归难度曲线与Boss | | 三选一件值(其余) | int [0,999],冒险表 kind×tier 列族 | adventure_table curio_value_*(GP 袋 / AP 件 / 恢复 / 刷新,provisional) | 令牌件值读表;道具件授予件数随秘宝件出池退役 | @@ -272,7 +272,7 @@ GP(显示名「GP」)是冒险内的一次性属性提升货币:战斗胜 | Boss 钥石掉落 | int [0,999],meta 表逐关行 | meta.tres boss_keystone 首杀 3 / 复杀 2(provisional) | 逐杀实时入账;精英怪掉 1 预留;消费方归元进度 | | GP 经济参数 | 商店表逐行 | 见 shop.tres gp_drops / level_gp_bonus / pool_shelf / price_a / price_b(provisional,以 shop.tres 为准;legacy products / price_level_bonus 随对照模式保留) | 掉落均值与区间(普通/精英/Boss)、关级掉落加值、货架基价、A/b 价格因子;公式语义归本文,数值所有权归难度曲线与Boss曲线调参批 | -结构冻结(非调参项):序列线性无跳关、关底 Boss 恒为末节点、倒下即冒险终、大奖励构成 = 通关部分回血 + 专长三选一(按档配比加权抽取——2026-10-11 迭代 20 换代;钥石退役出大奖励,改 Boss/精英击杀掉落——2026-09-30 拍板重构)、一冒险一主种子、收束点先清库后宣布的次序。 +结构冻结(非调参项):序列线性无跳关、终点恒为 Boss(终点可多个、各在路径最深处)、倒下即冒险终、大奖励构成 = 通关部分回血 + 专长三选一(按档配比加权抽取)、一冒险一主种子、收束点先清库后宣布的次序。 参数联动:恢复比例与通关回血比例越厚通关越有余量(对冲杠杆语义归难度曲线与Boss);三选一属性件/AP 件抬高后续战斗强度,件值/权重/上限改值须按难度曲线与Boss的口径重扫通关率带(回血比例自「血回满」改 20% 系难度上压方向,带判定顺带呈报)。 diff --git a/design/gdd/systems/战斗循环/敌人系统.md b/design/gdd/systems/战斗循环/敌人系统.md index 61ee71bf..28bd6f0c 100644 --- a/design/gdd/systems/战斗循环/敌人系统.md +++ b/design/gdd/systems/战斗循环/敌人系统.md @@ -64,14 +64,14 @@ ### 开战生成:主角数据行与一场 1–4 个敌人(行集可混编多种敌种) -战斗开始时,编排方给出遭遇坐标(关卡序号 + 节点深度),本系统据此在敌人表里取出该坐标的整个行集(一行或多行),把本战实际数量的敌人逐行生成出来——每行各按自己的数量行值实例化(单行 1 到 3 个),行集实例总数(各行开战骰后数量求和)不超过 4。同坐标多行即混编遭遇:各敌种同场上阵,生成序 = 表文件行序(行序即契约——目标顺位、摇号子流派生、开战叙述取首行都按它,加载期校验兜底:同坐标多行必须文件内相邻)。单行行集 = 既有形态:一场 1 到 3 个同种同属性敌人,来自同一行表值。战斗中敌人只减不增,不做召唤、增援、分裂。主角同时以当前血量入参生成,血量越界(高于上限或不超过 0)整单拒绝、不留半实例。 +战斗开始时,编排方给出遭遇坐标(关卡序号 + 深度带——节点深度所在的区间),本系统据此在敌人表里取出该坐标的整个行集(一行或多行),把本战实际数量的敌人逐行生成出来——每行各按自己的数量行值实例化(单行 1 到 3 个),行集实例总数(各行开战骰后数量求和)不超过 4。同坐标多行即混编遭遇:各敌种同场上阵,生成序 = 表文件行序(行序即契约——目标顺位、摇号子流派生、开战叙述取首行都按它,加载期校验兜底:同坐标多行必须文件内相邻)。单行行集 = 既有形态:一场 1 到 3 个同种同属性敌人,来自同一行表值。战斗中敌人只减不增,不做召唤、增援、分裂。主角同时以当前血量入参生成,血量越界(高于上限或不超过 0)整单拒绝、不留半实例。 生成拿到的是当时的表值快照:开战那一刻把每行的数值和池模板各抄一份,之后改表不影响已生成的单位。池模板快照成每实例自己的实例池(各技能冷却清零),此后各自独立摇号、互不干涉。某行的数量或攻击基线若配成了区间,由战斗结算用封闭随机流在开战时**按行各掷定一次**(每行掷自己的区间;掷定次数随行数——单行行集的掷定次数与既有口径逐位一致,混编不新增随机源形态)后传入确定值——本系统自身始终零随机;掷定后整场持久,攻击基线不逐拍重掷(数字要可读)。 | 规则 | 含义 | |---|---| | 敌方效果对全体生效 | 范围效果作用于所有存活敌人——混编放开后(2026-10-07 行集多行批)场上可多种敌种共存,结算语义按存活单位逐一生效、不依赖"场上全同种"前提;"只打某一个"的单体寻址暂不开放(见 P1) | -| 行集构成纪律 | 敌人表按(关卡序号 × 节点深度)存放,同一坐标行集允许多行、允许不同敌种混编。纪律三条,违规加载期返回错误并止动:①行集内 enemy_id 唯一(同一敌种在同行集仍只许一行);②同坐标多行必须表文件内相邻,行序 = 声明序 = 生成序(行序即契约);③行集实例总数(各行骰后数量求和)≤ 4,单行数量域 [1,3] 不变(UNIT_COUNT_MAX 语义 = 单种数)。行数不设上限;同关随深度换敌种合法 | +| 行集构成纪律 | 敌人表按(关卡序号 × 深度带)存放;深度带=节点深度的区间——逐局生成使单点深度不再固定,配池按带不按点,难度坡随带递增。同一坐标行集允许多行、允许不同敌种混编;Boss 行按终点配置,多终点各配一行(走哪条路决定打谁)。纪律三条,违规加载期返回错误并止动:①行集内 enemy_id 唯一(同一敌种在同行集仍只许一行);②同坐标多行必须表文件内相邻,行序 = 声明序 = 生成序(行序即契约);③行集实例总数(各行骰后数量求和)≤ 4,单行数量域 [1,3] 不变(UNIT_COUNT_MAX 语义 = 单种数)。行数不设上限;同关随深度换敌种合法 | | 主角数据行 | 主角战斗数值单独放一张全局单行表:生命上限、基础攻击力、护甲等级三字段(见调参表) | | 基础攻击恒存在 | 基础攻击不许配 0(配置为 0 加载期拒绝)——零基线乘任何百分比增益恒为零,"胜利路径恒有"的保障从数据层杜绝死锁 | | 先手攻击不是敌方技能拍 | 每次结算战斗段主角先手攻击顺位最前的存活敌人,这是固定动作;奖励侧的道具与增益是基础攻击之外的规划面伤害,归[地图战斗资源](地图战斗资源.md) | @@ -226,7 +226,7 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(**技能错 配置表共三张。数值纪律(2026-09-17 降级批定稿):**本文只锁字段、取值域与规则,行值一律读配置表(切片 `game/data/tables/` 的 enemy / skills / hero 表),不在本文登记具体数值——防双写失同步**;曲线调参所有权归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)。 -敌人表(按关卡坐标存放,每坐标行集一行或多行——多行即混编遭遇,构成纪律见核心规则「行集构成纪律」;单行行集 = 既有形态): +敌人表(按深度带坐标存放,每坐标行集一行或多行——多行即混编遭遇,构成纪律见核心规则「行集构成纪律」;单行行集 = 既有形态): | 参数 | 取值域 | 说明 | |---|---|---| diff --git a/design/gdd/ux/level-map.md b/design/gdd/ux/level-map.md index 902bc4c3..b83e6ed0 100644 --- a/design/gdd/ux/level-map.md +++ b/design/gdd/ux/level-map.md @@ -7,7 +7,7 @@ > **Template**: UX Spec > **覆盖范围**: 独立屏形态(关卡停点全景)· 入口停点 · 岔路停点 · 单链停点 · 放弃冒险入口 > **不覆盖**: 节点覆盖层(NodeOverlay——奖励/恢复兑付反馈,spec:[node-reward.md](node-reward.md))、商店覆盖层(spec:[shop.md](shop.md))、关卡结算屏([level-clear.md](level-clear.md))、战斗屏([battle.md](battle.md)) -> **机制权威**: [关卡节点地图](../systems/冒险循环/关卡节点地图.md)(选路、兑付、停点语义;节点图的来源随关卡节点图重构批重写,旧生成文档已删——只换图的来源,不换本屏的呈现语义);**系统契约**: [HUD框架](../systems/表现与支撑/HUD框架.md)(订阅纪律、模态层级、可访问性基线) +> **机制权威**: [关卡节点地图](../systems/冒险循环/关卡节点地图.md)(选路、兑付、停点语义);图的来源 = [关卡节点图生成](../systems/冒险循环/关卡节点图生成.md)(参数化长图——只换图的来源与形态,不换本屏的呈现语义;多终点时各终点均带 Boss 标记,标记语义不变、数量随图;图形态随参数变化,布局自适应,形态不进呈现代码);**系统契约**: [HUD框架](../systems/表现与支撑/HUD框架.md)(订阅纪律、模态层级、可访问性基线) --- diff --git a/待办清单.md b/待办清单.md index bfa576ef..47bb7dcb 100644 --- a/待办清单.md +++ b/待办清单.md @@ -101,19 +101,21 @@ **现状**:来源=playnote 用户试玩记录「关卡节点图展示得有问题,希望可以优化一下。可以参考哥布林弹珠的那种方式去移动」。2026-10-13 用户明确定性:**这是当前关卡节点图的重构,不是呈现优化**——理由是**现在的可选节点太少**(用户原话),所以不是换一种画法或移动方式就能解决的事。 +关联文档清单: +- 设计定稿 design/gdd/systems/冒险循环/关卡节点图生成.md v1.0(2026-10-21) +- 设计定稿 design/gdd/systems/冒险循环/关卡节点地图.md v2.0(2026-10-21) + **现行实态**(`level.tres` 实查,三关各 5 张模板):**第一关五张模板全是单链排列变体**——7 个节点=战斗 ×4 + 奖励 + 休整 + Boss,战斗深度序单调保难度坡,**变化面只有奖励与休整两位的先后次序**,全链零分叉,玩家在选路上**没有任何选择**;第二/三关是网状图(10 节点,带 `next` 分支,最大层宽 4–5),有分叉,但用户仍判选择量不足。参考方向=Peglin(哥布林弹珠)的节点图移动与选路方式。 **范围(重构面,非呈现面)**:节点数量、分叉度、选路自由度。连带三面——① 关卡节点图生成(旧版文档已删、随重构重写;现行 15 张骨架=3 关 ×5 已判过期,随重构清理);② [level-map](design/gdd/ux/level-map.md)(选路枢纽三停点布局定稿版,图结构改则屏面随之改);③ [敌人系统](design/gdd/systems/战斗循环/敌人系统.md)(遭遇表按 `enemy.tres` 的 (level_index, node_depth) 坐标索引,节点数与编号一改,行集坐标与首遇教学位断言面全部随动)。 -**量化要求补登(2026-10-16 playnote 用户补写)**:「需要统计一下第 123 关 path 的路径长度,路径长度需要递增,并且后续关卡的节点数增幅应该更大」(第 123 关=第 1/2/3 关)——重构设计讨论的验收方向两条:先实测三关路径长度基线,再定递增曲线与后续关增幅尺度。 +**量化要求补登(2026-10-16 playnote 用户补写)**:「需要统计一下第 123 关 path 的路径长度,路径长度需要递增,并且后续关卡的节点数增幅应该更大」(第 123 关=第 1/2/3 关)——已定稿成验收形态:读数=最长路径步数与节点总数(口径见[关卡节点图生成](design/gdd/systems/冒险循环/关卡节点图生成.md)验收标准),两者逐关递增、节点总数增幅 Δ(L2→L3)>Δ(L1→L2);基线采集发起权归用户,读对象=生成图(旧模板已裁不作参考)。 **前置(用户 2026-10-13 裁)**:**须先做文档设计讨论,不可直接开发**——参考调研+重构方案先行、过人闸后才可开卡。版本标准侧已登记为 Alpha 待做项,见 [08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「一 · 系统 · 冒险循环」。 -**缺口**:还差参考调研+重构方案的设计讨论(含路径长度基线实测与递增曲线两条验收方向),过人闸后才能开卡。 +**归属**:[关卡节点地图](design/gdd/systems/冒险循环/关卡节点地图.md)(图结构与节点语义,主责)+ [关卡节点图生成](design/gdd/systems/冒险循环/关卡节点图生成.md)(产出规格与生成参数)+ [level-map](design/gdd/ux/level-map.md)(选路呈现)+ [敌人系统](design/gdd/systems/战斗循环/敌人系统.md)(遭遇行集坐标连带);版本标准侧已登记为 Alpha 待做项,见 [08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「一 · 系统 · 冒险循环」 -**归属**:[关卡节点地图](design/gdd/systems/冒险循环/关卡节点地图.md)(图结构与节点语义,主责)+ 关卡节点图生成(旧版文档已删、随重构重写)+ [level-map](design/gdd/ux/level-map.md)(选路呈现)+ [敌人系统](design/gdd/systems/战斗循环/敌人系统.md)(遭遇行集坐标连带);版本标准侧已登记为 Alpha 待做项,见 [08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「一 · 系统 · 冒险循环」 - -**状态**:待文档设计 +**状态**:文档设计已闭合 #### 天赋树实装批登记欠账余两件——AP 上限 clamp 与三选一刷新软上限(2026-10-12 登记,来源=批次移交,设计面=文档轨) From 9af9b5807e6e530653a1a0318e72b96cb0f9d5e5 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 04:51:29 +0800 Subject: [PATCH 53/59] =?UTF-8?q?docs(=E8=BF=AD=E4=BB=A332=E7=A7=BB?= =?UTF-8?q?=E4=BA=A4=E9=A1=B9=E8=A1=A5=E7=99=BB=E8=AE=B0):=20=E9=97=A8?= =?UTF-8?q?=E7=A5=A8=E4=B8=89=E5=A4=84=E4=B8=8E=E5=B7=A2=E7=A9=B4=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=E8=A1=A8=E8=BF=B0=E4=B8=A4=E6=9D=A1=E5=BE=85=E8=A3=81?= =?UTF-8?q?=E9=A1=B9=E6=81=A2=E5=A4=8D=E7=99=BB=E8=AE=B0=E2=80=94=E2=80=94?= =?UTF-8?q?=E6=94=B6=E5=B0=BE=E5=88=A0=E6=9D=A1=E7=9B=AE=E6=97=B6=E8=AF=AF?= =?UTF-8?q?=E5=B0=86=E6=9C=AA=E5=86=B3=E4=B8=80=E5=B9=B6=E6=B6=88=E4=BA=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 判据「未决先迁再死」违例自查所出:原承载句在「代码注释禁用词清扫批」条目(完成即整条删除) 与卡①反哺专条(已写入即删)内,删后 design/ 与待办清单均无登记处,门票三处与巢穴逐处定性失去追踪面。 两条各立条目(不并入「冒记案遗留待裁两项」——该标题为登记元数据、禁改),状态=待文档设计。 --- 待办清单.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/待办清单.md b/待办清单.md index 47bb7dcb..b28c9d88 100644 --- a/待办清单.md +++ b/待办清单.md @@ -720,3 +720,27 @@ **归属**:`game/tests/`(代码域,随下一个触碰 game/ 的批次顺带清) **状态**:待写卡 + +--- + +#### 迭代 32 移交项一——奇物门票三处玩家文案待定性后传导(2026-10-21 登记,来源=批次移交,设计面=文档轨) + +**现状**:「门票(专长门票)→专长凭证」已在 [术语表](design/gdd/术语表.md) 「退役词对照」在册;迭代 32 卡① 清了 `game/` 注释面的 36 处,但下列三处是**数据值与玩家可见文案**、属 奇物/专长 归类表述,需文档侧先定性才动,故本批只移交不改:①`game/data/tables/shop.tres:86` `"display_name": "奇物门票"`;②③`game/presentation/curio_interact_controller.gd:165`/`:166` 交互文案「奇物门票/选定即开一次奇物三选一」。代码闸拦不到它们——S11 只取注释面(.gd 取 # 后、.tres 取 ; 后),数据值与 UI 文案不在其扫描语义内。关联文档:[奇物](design/gdd/systems/冒险循环/奇物.md)(归类口径 owner,现行版本以文首状态行为准)。用户 2026-10-21 裁=与本清单「2026-10-18 冒记案遗留待裁两项」第②项(资源成员判据句)同源,待该项裁决后走传导批。 + +**缺口**:奇物/专长 归类定性一次(随「2026-10-18 冒记案遗留待裁两项」②一并裁);裁后据结论定三处文案改法。 + +**归属**:design/gdd/systems/冒险循环/奇物.md(定性面)+ `game/data/tables/shop.tres`/`game/presentation/curio_interact_controller.gd`(传导面,代码域) + +**状态**:待文档设计 + +--- + +#### 迭代 32 移交项二——巢穴机制表述逐处定性待裁(2026-10-21 登记,来源=批次移交,设计面=文档轨) + +**现状**:[术语表](design/gdd/术语表.md) 「退役词对照」在册一条「巢穴(机制表述)→危险格,世界观风味层的巢穴隐喻〔00-游戏概念/美术纹样名〕除外」——口径已裁,缺的是**逐处判定**:`design/gdd/` 现仍有「巢穴」用词(00-游戏概念 8 处、01-核心循环 3 处、跨局循环/秘宝 3 处,04-美术音频方向/排雷玩法/HUD框架/设置与本地化 各 1 处,术语表自身 3 处),哪些属机制表述(须换「危险格」)、哪些属风味层(保留)未定性。代码注释面本条不清——迭代 32 卡① 的 S11 扫描显式排除「巢穴」(玩家专名+术语表自带除外注)。用户 2026-10-21 裁=待裁范围后另立批,本批只登记。关联文档:design/gdd/术语表.md(用词纪律 owner)。 + +**缺口**:一次文档设计讨论——按上列文件逐处判定机制表述与风味层的分界,产出可执行的换代清单。 + +**归属**:design/gdd/ 各件(机制表述面)+ design/gdd/术语表.md(口径与除外注) + +**状态**:待文档设计 From 3cdf40d8f88c088851db22d23c81399a61b108e5 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 04:54:08 +0800 Subject: [PATCH 54/59] =?UTF-8?q?docs(=E6=AE=8B=E7=95=99=E7=A6=81=E5=AD=97?= =?UTF-8?q?=E6=9D=A1=E7=9B=AE=E8=AE=A2=E6=AD=A3):=20=E7=8E=A9=E5=AE=B6?= =?UTF-8?q?=E9=9D=A2=E6=AE=8B=E7=95=99=E7=A6=81=E5=AD=97=E6=B8=85=E6=89=AB?= =?UTF-8?q?=E7=8E=B0=E7=8A=B6=E6=AE=B5=E6=8C=89=202026-10-21=20=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=AE=9E=E6=9F=A5=E6=8D=A2=E4=BB=A3=E2=80=94=E2=80=94?= =?UTF-8?q?=E4=BA=94=E5=A4=84=E6=94=B9=E8=AE=B0=E7=8E=B0=E5=AD=98=E4=B8=89?= =?UTF-8?q?=E5=A4=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 迭代 32 卡① 已清掉其中两处(战斗日志与横幅「完美排雷」→「完美封印」),条目未跟改; 另两处路径与行号漂移(status_slot_row 移入 views/ 现 :40、board_view 现 :730、ui_kit 现 :36)。 标题「五处」为登记元数据不改,现况计数写正文;归属序号随现况同步(字形项现为③)。 --- 待办清单.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/待办清单.md b/待办清单.md index b28c9d88..a4185f2c 100644 --- a/待办清单.md +++ b/待办清单.md @@ -693,16 +693,14 @@ #### 玩家面残留禁字清扫——图例/明细/日志/字形五处(2026-10-20 登记,来源=批次移交,设计面=工程直入) -**现状**:迭代 31 卡① 已把 `game/` 的金币/插旗/雷格/惩罚格/`flag` 清零,但玩家可见文本仍残留「雷/排雷/插」五处(v3.15 命名纪律:玩家面禁「雷」,危险格对外风味=地下城陷阱/怪物巢穴):①`legend_overlay.gd:11` 图例行「插错可左键直接挖开…危险格吃**挖雷**惩罚」;②`status_slot_row.gd:42` 与 `settlement.tres:14` 明细来源名 `"mine_hit": "踩雷"`;③`battle_log_view.gd:194` 战斗日志「本板**完美排雷**已破——归因此封印」;④`board_fx_view.gd:102` 横幅「**完美排雷** ×2」;⑤`board_view.gd:737` 已开危险格单字字形 `glyph = "雷"`。①-④ 纯文案零风险;⑤ 改字形会动 golden 基线,须同步重制 C 档基准。开发注记面(`ui_kit.gd:37` 常量名 `RED_MINE` 与其注释)属内部语,按纪律保留。 +**现状**:迭代 31 卡① 已把 `game/` 的金币/插旗/雷格/惩罚格/`flag` 清零;标题里的「五处」是 2026-10-20 登记时的原述(标题为登记元数据不改),2026-10-21 逐处复查代码后**现存三处**(v3.15 命名纪律:玩家面禁「雷」,危险格对外风味=地下城陷阱/怪物巢穴):①`game/presentation/views/legend_overlay.gd:11` 图例行「插错可左键直接挖开…危险格吃**挖雷**惩罚」;②`game/presentation/views/status_slot_row.gd:40` 与 `game/data/tables/settlement.tres:14` 明细来源名 `"mine_hit": "踩雷"`;③`game/presentation/views/board_view.gd:730` 已开危险格单字字形 `glyph = "雷"`(原述 :737 系行号漂移,且文件已迁入 `views/`)。①② 原列的第③④两处(战斗日志与全屏横幅的「**完美排雷**」)已由迭代 32 卡① 换成「完美封印」,不再是残留。①② 纯文案零风险;③ 改字形会动 golden 基线,须同步重制 C 档基准。开发注记面(`game/presentation/views/ui_kit.gd:36` 常量名 `RED_MINE` 与其注释、`board_cell_unit.gd` 与数据表注记里的「雷」字内部语)属内部语,按纪律保留。 -**归属**:`game/presentation/` 与 `game/data/tables/settlement.tres`(走独立 worktree 批;⑤ 连带渲染基线) +**归属**:`game/presentation/views/` 与 `game/data/tables/settlement.tres`(走独立 worktree 批;③ 连带渲染基线) **状态**:待写卡 --- - - #### 结算明细日志行序重锚批(2026-10-21 登记,来源=批次移交,设计面=反哺点) **现状**:迭代 32 卡① N7 改动互换 `seal_miss`/`insurance_used` 两行日志顺序并改写豁免态 highlight(豁免态=insurance_used 行先行且 highlight 置空;未豁免态=两行相对序不变但 `seal_miss` 发射时点后移——完整对照见 git 提交 d00f24a8 批内实现报告,报告已退役);`playtest_logger._on_step_row` 逐行落盘含 highlight 字段,与基线数据逐项比对的 JSONL sha256 校验必红,实现批按规未发起、11 号闸落 skip。**用户 2026-10-21 裁=批准另立重锚批,发起时点另定**(重锚批只能由用户发起)。 From 7493aebca86c3b67bf32c7440e9d0e275b579c64 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 05:51:17 +0800 Subject: [PATCH 55/59] =?UTF-8?q?chore(=E6=96=87=E6=A1=A3=E7=BC=BA?= =?UTF-8?q?=E9=99=B7=E8=AE=A2=E6=AD=A3=E4=B8=8E=E6=9C=BA=E6=A3=80=E8=A1=A5?= =?UTF-8?q?=E4=BB=B6):=20=E5=9B=9B=E4=BB=BD=E6=A0=B9=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=94=A8=E8=AF=8D=E4=B8=8E=E6=AD=BB=E6=8C=87=E8=AE=A2=E6=AD=A3?= =?UTF-8?q?=EF=BC=8B=E6=96=B0=E5=A2=9E=E5=BC=95=E7=94=A8=E5=8F=AF=E6=A0=B8?= =?UTF-8?q?=E6=9C=BA=E6=A3=80=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修文档缺陷四处:AGENTS.md「收口」×2、「不得」×3 换白话;roadmap.md:87「对拍」「标旗」换代; reports/README.md 指向已迁移的 design/gdd/06-待办清单.md 改指仓库根;待办清单 iter19 遗留第⑦项 前半「数据配置.md:223 历史行死指」实查核销(该文件版本史行已随禁写变更记录规约消亡,现 212 行)。 补机检:tools/doc_ref_audit.py 核文档内「文件:行号」指针的目标存在性与行界,带扫描面为空与 引用数为零双自检;双向变异证据——注入不存在路径 EXIT=1、注入超界行号 EXIT=1、还原 EXIT=0。 doc_term 扫描面扩到四份根文件:扩面前实测这批文件自身含 3 处用语表废止词,先改现实再扩面, 扩面后「疑似现行」0、注入「完美排雷」见红 EXIT=1、还原 EXIT=0。 08d 引用可核暂不注册进闸壳:建档须改 game/tests/.gates/baseline.json,触 game/ 即要求代码域全量测试, 文档域批按测试两入口铁规零跑——注册欠账已登记待办清单。内容锚核对实测 81 处出 58 条未命中(约七成噪声), 按建议级交付不判红。文档域闸全绿。 --- AGENTS.md | 10 +- design/gdd/01-核心循环.md | 1 + reports/README.md | 2 +- roadmap.md | 2 +- tools/doc_ref_audit.py | 219 ++++++++++++++++++++++++++++++++++++++ tools/doc_term_audit.py | 10 +- tools/run_all_gates.sh | 3 + 待办清单.md | 19 +++- 8 files changed, 254 insertions(+), 12 deletions(-) create mode 100644 tools/doc_ref_audit.py diff --git a/AGENTS.md b/AGENTS.md index 2735d352..8d747e33 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -31,7 +31,7 @@ - `artwork/` — 在途图像素材唯一工作区(文档归文档/在途图归一处/终稿归游戏);整目录不入 git(.gitignore 强制),收口归档 `archive/` - `game/assets/art/` — 已验收终稿(入包被游戏加载);`game/` — 游戏工程本体(代码 + smoke/ 冒烟 + tests/ 单元集成) - `sim-data/` — 机器读数据产物;数据件不入 git(入库例外 = README+analyze.py+growth_model.py);MC 锚与读数常驻留盘,无数值调整禁重跑 -- `tools/` — python 工具脚本;`archive/` — 收口归档 zip(gitignored) +- `tools/` — python 工具脚本;`archive/` — 批次完结归档 zip(gitignored) - `reports/` — 过程件容器:**需求卡片**(写卡段产出,实现批的输入合同)+迭代批产出物(实现报告/代拍板追认单/GDD 反哺点清单);**实现批唯一可写目录**,只放 .md,不是事实源(细则见 `reports/README.md`) - 根目录:`README.md`(纯指路牌:设计/流程/当前位/待办四个链接,零规则重述)、`roadmap.md`(里程碑+迭代总表六列+顶部「当前位」节=现在做什么)、`待办清单.md`(流水线唯一登记处,条目级待办与状态)、`体验验证清单.md`(需真人试玩才能下结论的验证项)、`stage.txt`/`review-mode.txt`(运行开关);仓库根禁止再设会话状态文件(细则见 doc-conventions 第 10 节) @@ -56,22 +56,22 @@ - **仓库根禁止设会话状态文件**(`active.md` 已废除)——现状看 roadmap「当前位」,待办看待办清单,过程看 git 提交信息,产出物看 `reports/`;任何文档禁止另设「当前状态快照」节,两处记同一件事必然漂移(细则见 doc-conventions 第 10 节) - 测试执行两入口铁规——只有迭代 loop 开发与用户点名两个触发入口;其余会话零测试,需测试支撑先请示并注明未跑测 - 交付前验收 = 跑 `tools/run_all_gates.sh` **按改动域**全绿(唯一入口、唯一闸清单、唯一域划分,禁在文档另列);合回 master 由 worktree-guard 按 diff 推域校验回执强制(process-conventions §3) -- **两类批**——**迭代批**(代码实现,`/iter` 发射):**禁写 `design/` 整个目录与两份根流程清单(`待办清单.md`/`体验验证清单.md`)**(含新增/修改/删除),设计文档对它只读、是写测试与实现代码的输入依据;两份流程清单的条目状态只由流水线各段推进,实现批不得顺手改;产出物只准写 `reports/`;批末只跑代码域闸。**非迭代批**(工具/规则/文档改动):不占 roadmap 迭代号,按改动域跑闸。文档内容的落地走五段流水线相应段(文档设计段入口=doc-design 技能;登记条目格式由流水线闸强制) +- **两类批**——**迭代批**(代码实现,`/iter` 发射):**禁写 `design/` 整个目录与两份根流程清单(`待办清单.md`/`体验验证清单.md`)**(含新增/修改/删除),设计文档对它只读、是写测试与实现代码的输入依据;两份流程清单的条目状态只由流水线各段推进,实现批禁止顺手改;产出物只准写 `reports/`;批末只跑代码域闸。**非迭代批**(工具/规则/文档改动):不占 roadmap 迭代号,按改动域跑闸。文档内容的落地走五段流水线相应段(文档设计段入口=doc-design 技能;登记条目格式由流水线闸强制) - 五段流水线铁律——一切工作按「登记 → 文档设计/美术设计 → 写需求卡片 → 迭代编排 → 实现」推进,段间不自动流转、每段转进由用户发令;编入迭代的卡片必须设计闭合+零待裁点,流水线闸 `tools/pipeline_gate.py` 强制(已注册进 run_all_gates.sh 文档域);实现段零裁断——卡片没写清=上游缺陷,停该卡退回上游,禁内联求裁(process-conventions §2,格式与状态机=doc-conventions §12) - MC/模拟:无数值改动零跑;档位硬闸见 `sim-data/README.md`「MC 采集档位表」,一档只能由用户发起 - 闸机轮次纪律:新码先孤立验证 → 出红只跑红件最小单元 → 长批先最小参数试车 → 开工扫坑册(process-conventions §6) - 变异验证——新增/改写验收函数必须变异变红才算验收成立;无变异红记录只写「已实现,拦截能力未证」(test-conventions §6) -- **验收闭合**——每个需求点与每个行为改动都要有从真实入口进入的验收断言,撤销该改动能让对应断言变红;禁删断言/放宽阈值换绿;合回前独立验收审计未过不得合并(细则=test-conventions §9+iter 技能第 5 步) +- **验收闭合**——每个需求点与每个行为改动都要有从真实入口进入的验收断言,撤销该改动能让对应断言变红;禁删断言/放宽阈值换绿;合回前独立验收审计未过则禁止合并(细则=test-conventions §9+iter 技能第 5 步) - 规则评估——没在真实任务上评估过的规则修订,不算完成。 - 中间产物吸收即死——结论先吸收进权威文档、未决先迁待办清单,文件即删且永不提交(doc-conventions 第 11 节) - **禁写变更记录**——文档与代码文件内一律禁设「版本历史/修订记录/变更记录/修改记录/更新记录/更新日志」节或表格,禁写「本版改了哪些条款」式逐版本叙述与 `# 2026-xx-xx 缺陷修批——` 式行内修订注记;沿革只进 git commit log。版本号可作文档现行身份标记留在文首状态行与正文引用中(doc-conventions 第 5 节,机检闸 gdd_lint R4 反转拦截) - 用语红线——一切对用户输出禁自造黑话,需要作者解释的词必须展开成完整白话句(doc-conventions 第 4 节三形态表) - 呈报四问(读后自检制)——向用户首次完整呈报一件事(需求/缺陷/方案/结论)时,写完先自查:读者只读这一段,能否不看原文答出——① 现状差在哪:现在是什么、缺什么;② 你建议做什么:做完预期什么效果、会动到哪些面;③ 为什么选这个做法:考虑过、放弃过哪些别的路;④ 做完怎么验证:哪些还有把握不足。哪问答不出就补哪问,禁靠加小标题凑数;三句话能说清的小件合并为三句:现状一句、建议与验证一句、没把握的一句;后续追问与推进不必重跑全框架 -- 真人检测只登记不阻塞——登记进体验验证清单/实现报告即完成义务,禁以等目检为停工理由或收口前置 +- 真人检测只登记不阻塞——登记进体验验证清单/实现报告即完成义务,禁以等目检为停工理由或当作合回的前置条件 - 文件头 = `##` 文档注释,介绍本模块是什么;禁写变更叙事(改动史查 git log);禁文档反向链接(code-conventions §1.4.1) - 数值单一事实源——玩法数值只存 `data/tables/`(.tres)经 ConfigDB 单点读取;禁数值字面量与自建 `load()` 表路径 - RNG 单点——禁 `randomize()`/自建 RandomNumberGenerator,随机只经 `RngService` 统一流 - 架构事实唯一源——架构事实只认 `design/engineering/architecture/architecture.md`;禁立第二架构文档或决策文档体系,历史决策记录只进 git commit log - Core 层零 UI 依赖——完整战斗必须可 `--headless --script` 跑通;fail-fast——数据校验错误一律致命中止,无软回退 -- spec-AC 一致性——规约与验收标准不得在同一输入上给出不同答案;评审隔离——`/design-review` 必须独立会话跑(与 `/design-system` 隔离) +- spec-AC 一致性——规约与验收标准禁止在同一输入上给出不同答案;评审隔离——`/design-review` 必须独立会话跑(与 `/design-system` 隔离) - 像素结构件——先抄后造、验收写成像素级判据、±1px 坐标推导(process-conventions 第 7 节) diff --git a/design/gdd/01-核心循环.md b/design/gdd/01-核心循环.md index 124f3178..eab7ea80 100644 --- a/design/gdd/01-核心循环.md +++ b/design/gdd/01-核心循环.md @@ -160,3 +160,4 @@ **获取概率提升**是元进度/营地的合法提升轴(可提升=奇物高档位出现率/秘宝解锁进度/地图 T3/T4 权重),但**不动保底**——保底是承诺不是概率,禁止任何概率件改变 T3「每板必有回复」类承诺。 **专长 rarity 语义约束**:Boss 三选一候选按档配比或加权抽取,使罕见度对出现率生效(字段双脱钩修复——此前 rarity 不影响抽选也不稳代表幅度);具体配比归调参批。 + diff --git a/reports/README.md b/reports/README.md index 15e1e379..3216da5c 100644 --- a/reports/README.md +++ b/reports/README.md @@ -18,7 +18,7 @@ - **不放设计结论。** 本目录的文件是"待处理的申请单",不是事实源。反哺点由你在会话中讨论定稿后, 另开文档批写进 `design/`,写完即可删除本目录对应条目。 - **不放图。** 图像白名单不含本目录,放了会被熵增闸判红。 -- **不放进度状态。** 现在做什么看根 `roadmap.md` 顶部「当前位」节,待办与待裁看 `design/gdd/06-待办清单.md`(2026-10-18 用户裁:根目录会话状态文件已废除,本目录也不许兼做状态记录)。 +- **不放进度状态。** 现在做什么看根 `roadmap.md` 顶部「当前位」节,待办与待裁看仓库根 `待办清单.md`(2026-10-18 用户裁:根目录会话状态文件已废除,本目录也不许兼做状态记录)。 ## 生命周期 diff --git a/roadmap.md b/roadmap.md index 12e50979..8fbe34cf 100644 --- a/roadmap.md +++ b/roadmap.md @@ -84,7 +84,7 @@ > **迭代粒度界定(对齐敏捷迭代/Sprint)**:一个迭代 = 一句迭代目标 + **3–8 个更改任务** + 一份计划书 loop + 一次合并登记,交付一个可验证增量(≈一次迭代交付)。单交付物不成迭代——并入相邻迭代当任务卡;用户输入闸未解的任务不进迭代(留待办清单当 backlog,解闸后编入下一个迭代);**迭代周期 ≈ 一周左右**(2026-10-11 用户裁定——原「软时间盒 ≤3 个工作日,超限即切迭代」系 3abb3bd2 成文时自造、用户从未立过此规,就此废弃)。**里程碑 = 2–4 个迭代的发布级目标 + 出口验收闸(≈Release)**。 > 1. **计划书**(`.zcode/plans/<迭代名>-loop-plan-<日期>.md`):迭代目标与完成定义 / 现状事实(代码级,开工自行复核)/ 设计契约(违反即返工,标 🔴 触碰=L3 停机)/ 范围边界 / 任务卡 T0..Tn(逐卡估时)/ 验证闸 / 异常分级 / 代拍板白名单。 -2. **T0 开工**:建 worktree + 基线复读记档(冒烟/探针/三闸/MC 对拍基准)+ `git status` 归属核对(并行遗留只标旗不碰)。 +2. **T0 开工**:建 worktree + 基线复读记档(冒烟/探针/三闸/MC 与基线数据逐项比对基准)+ `git status` 归属核对(并行遗留只登记不触碰)。 3. **循环骨架**:一轮 = 一个任务卡——读卡 → 对事实源 → 实装 → 轻闸全绿 → 提交(代拍板随 commit 记录)→ 状态记录追加(查撞号)→ 下一轮。单 worktree 多点提交一次合并;轮内禁开第二个 worktree;基线每轮开工时点重测;断点续跑 = `git log` 对任务卡定轮次 + 重跑当轮轻闸。 4. **轻闸**(每轮必跑,headless):`tools/run_all_gates.sh --quick`(迭代中段自检档)。 5. **重闸**(批末 Tn):`tools/run_all_gates.sh` **按本批改动域跑**(触及 `game/` → `--code`,这是代码域唯一触发;不触及 `game/` 的一切路径 → `--docs`;一次改动同批混触两域 → 不带参数全量),所选域全绿——闸件清单、顺序与域划分只在该脚本里定义,本文件与 AGENTS.md/规约均不另列;改闸件自身(`tools/` 下机检脚本与闸壳)不占合回全量,质量义务=落批时的变异验证;涉核心的 MC 与基线逐位比对、素材批的机检断言另行。 diff --git a/tools/doc_ref_audit.py b/tools/doc_ref_audit.py new file mode 100644 index 00000000..3e400913 --- /dev/null +++ b/tools/doc_ref_audit.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python3 +r"""doc_ref_audit.py — 文档内代码引用可核检查(机检) + +职责:现行文档里凡写「某文件:第几行」,就该指得动。本工具核两件事: + ①路径可解析——目标文件在 git 受控文件清单里存在; + ②行号在界内——引用的行号不超过目标文件的实际行数。 +动机:条目与规约常写 `board_view.gd:737` 这类指针,代码前进后行号漂移、文件迁移改名, +账面就与现实脱节而无人知(2026-10-21 迭代 32 收尾时实测抓到两例)。 + +扫描面:`design/` 现行文档树 + 四份根文件(`待办清单.md`/`体验验证清单.md`/`roadmap.md`/`AGENTS.md`)。 +排除面:`reports/` 与 `design/research/`——两处是中间文档暂存地(doc-conventions 第 11 节), +入内文件按「吸收即死」退役,历史件不回溯改,故不入本闸判据。 + +自检二道(防假绿):扫描文件数为零 ⇒ FAIL;抽取到的引用数为零 ⇒ FAIL。 +(正则被改写失手或路径写错时,检查会静默空转并报绿——与 static_scan 各段同规。) + +判据分两档: + 红(判 FAIL)=路径不存在/行号超界; + 建议(只报告)=同名文件有多条路径需要人工定位/`--anchors` 的内容锚没在目标行附近找到。 + +用法: + python tools/doc_ref_audit.py # 全扫,报告模式 + python tools/doc_ref_audit.py --strict # 有红项时 exit 1(供门禁) + python tools/doc_ref_audit.py --anchors # 追加内容锚核对(只报告,不判红) + python tools/doc_ref_audit.py ... # 只扫指定文件 +exit:0=全绿 / 1=有红项(--strict)/ 2=扫描面异常(目录缺失) +""" +import argparse +import io +import os +import re +import subprocess +import sys +from pathlib import Path + +REPO = Path(__file__).resolve().parents[1] + +SCAN_DIRS = ["design"] +SCAN_EXCLUDE_DIRS = ["design/research"] +ROOT_FILES = ["待办清单.md", "体验验证清单.md", "roadmap.md", "AGENTS.md"] + +# 引用形态:路径或文件名 + 扩展名 + 半/全角冒号 + 行号。反引号可包在中间或外面, +# 因此先抓到扩展名为止,冒号允许紧跟或在反引号之后。 +REF_RE = re.compile( + r"([\w./一-鿿-]+\.(?:gd|tres|sh|py|json|md|cfg|yml|yaml|txt|png|html))" + r"[`”』」]?\s*[::]\s*(\d+)" +) +# 内容锚:同一行内的反引号片段或「」内文本,取长度 ≥4 的第一个非引用片段 +ANCHOR_RE = re.compile(r"`([^`\n]{4,60})`|「([^」\n]{4,60})」") +ANCHOR_WINDOW = 12 +# 留档信号(与 doc_term_audit 同口径):同句带日期或退役/注销类说明时,指向已不存在的路径 +# 属历史叙述而非现行指针,降为建议级报出、不判红。 +ARCHIVE_RE = re.compile( + r"\d{4}-\d{2}-\d{2}|退役|注销|已删|已废除|已废|废除|作废|历史|原名|改名|迁入|迁到|移到|迁至" +) + + +def tracked_files(): + out = subprocess.run( + ["git", "-c", "core.quotepath=false", "-C", str(REPO), "ls-files"], + capture_output=True, text=True, encoding="utf-8", errors="ignore", + ) + if out.returncode != 0: + return None + return {l.strip().strip('"').replace("\\", "/") for l in out.stdout.splitlines() if l.strip()} + + +def collect_docs(explicit): + if explicit: + return [p for p in explicit if Path(p).is_file()] + paths = [] + for d in SCAN_DIRS: + root = REPO / d + if not root.is_dir(): + return None + for p in sorted(root.rglob("*.md")): + rel = p.relative_to(REPO).as_posix() + if any(rel.startswith(x + "/") for x in SCAN_EXCLUDE_DIRS): + continue + paths.append(rel) + for f in ROOT_FILES: + if (REPO / f).is_file(): + paths.append(f) + return paths + + +def resolve(name, doc_rel, index, bybase): + """返回 (命中路径列表, 解析方式)。方式=exact / ambiguous / none。""" + name = name.strip("./") + if "/" in name: + for cand in ( + os.path.normpath(os.path.join(os.path.dirname(doc_rel), name)).replace("\\", "/"), + os.path.normpath(name).replace("\\", "/"), + ): + if cand in index: + return [cand], "exact" + return [], "none" + cands = sorted(bybase.get(name, [])) + if not cands: + return [], "none" + if len(cands) == 1: + return cands, "exact" + return cands, "ambiguous" + + +def line_count(path, cache): + if path not in cache: + try: + cache[path] = len(io.open(REPO / path, encoding="utf-8", errors="ignore").read().splitlines()) + except OSError: + cache[path] = 0 + return cache[path] + + +def anchor_of(line, name): + """取同句里可当内容锚的片段:反引号或「」内、长度 ≥4、且自身不是文件路径。""" + for m in ANCHOR_RE.finditer(line): + frag = (m.group(1) or m.group(2)).strip() + if name.split("/")[-1] in frag: + continue + if re.search(r"\.(gd|tres|sh|py|json|md|yaml|yml|html|png)$", frag): + continue + if re.fullmatch(r"[\d:~\-]+", frag): + continue + return frag + return None + + +def check(doc_rel, index, bybase, cache, anchors=False): + reds, advises = [], [] + text = io.open(REPO / doc_rel, encoding="utf-8", errors="ignore").read() + for ln, line in enumerate(text.splitlines(), 1): + for m in REF_RE.finditer(line): + name = m.group(1).lstrip("①②③④⑤⑥⑦⑧⑨⑩〔[[((「」·、。,,;;") + num = int(m.group(2)) + hits, how = resolve(name, doc_rel, index, bybase) + if how == "none": + if ARCHIVE_RE.search(line): + advises.append("%s:%d 引用已退役件 指 `%s`——同句带日期或退役/注销类说明,按留档处理" % (doc_rel, ln, name)) + else: + reds.append("%s:%d 引用可核/路径不存在 文档指 `%s`,git 受控文件清单里没有这件" % (doc_rel, ln, name)) + continue + if how == "ambiguous": + advises.append("%s:%d 同名多路径 指 `%s`——命中 %d 件(%s),需写全路径" % ( + doc_rel, ln, name, len(hits), ", ".join(hits[:3]))) + target = hits[0] + total = line_count(target, cache) + if num > total: + if ARCHIVE_RE.search(line): + advises.append("%s:%d 行号已越界(留档句) 指 `%s:%d`,目标现 %d 行——同句带退役/日期说明" % ( + doc_rel, ln, name, num, total)) + else: + reds.append("%s:%d 引用可核/行号超界 指 `%s:%d`,目标文件现只有 %d 行" % (doc_rel, ln, name, num, total)) + continue + if anchors: + frag = anchor_of(line, name) + if frag: + lines = io.open(REPO / target, encoding="utf-8", errors="ignore").read().splitlines() + lo, hi = max(0, num - 1 - ANCHOR_WINDOW), min(len(lines), num + ANCHOR_WINDOW) + window = "\n".join(lines[lo:hi]) + if frag not in window: + advises.append("%s:%d 内容锚未命中 指 `%s:%d`,同句片段「%s」不在该线 ±%d 行内" % ( + doc_rel, ln, os.path.basename(name), num, frag[:28], ANCHOR_WINDOW)) + return reds, advises + + +def main(): + ap = argparse.ArgumentParser(description="文档内代码引用可核检查") + ap.add_argument("files", nargs="*", help="指定文件;缺省扫 design/ 现行树+四份根文件") + ap.add_argument("--strict", action="store_true", help="有红项时 exit 1") + ap.add_argument("--anchors", action="store_true", help="追加内容锚核对(只报告)") + args = ap.parse_args() + + index = tracked_files() + if index is None: + print("引用可核 FAIL:git ls-files 取不到受控文件清单(扫描面异常)") + return 2 + docs = collect_docs(args.files) + if docs is None: + print("引用可核 FAIL:扫描目录缺失(design/ 不在位)") + return 2 + if not docs: + print("引用可核 FAIL:扫描面为空——路径写错导致的静默假绿") + return 1 + + bybase = {} + for p in index: + bybase.setdefault(p.rsplit("/", 1)[-1], []).append(p) + + cache, all_reds, all_adv = {}, [], [] + total_refs = 0 + for doc in docs: + reds, adv = check(doc, index, bybase, cache, anchors=args.anchors) + total_refs += doc_ref_count(doc) + all_reds += reds + all_adv += adv + if total_refs == 0: + print("引用可核 FAIL:抽取到的引用数为零——正则或扫描面失手,属假绿防线") + return 1 + + for r in all_reds: + print(r) + print("── 引用可核:扫描 %d 件文档 · 抽取引用 %d 处 · 红项 %d · 建议 %d" % ( + len(docs), total_refs, len(all_reds), len(all_adv))) + if all_adv: + for a in all_adv[:25]: + print(" (建议)" + a) + if len(all_adv) > 25: + print(" (建议)…另有 %d 条" % (len(all_adv) - 25)) + return 1 if (args.strict and all_reds) else 0 + + +def doc_ref_count(doc_rel): + text = io.open(REPO / doc_rel, encoding="utf-8", errors="ignore").read() + return sum(len(REF_RE.findall(l)) for l in text.splitlines()) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/doc_term_audit.py b/tools/doc_term_audit.py index 9ba0c203..3d5c8a8e 100644 --- a/tools/doc_term_audit.py +++ b/tools/doc_term_audit.py @@ -14,8 +14,9 @@ r"""doc_term_audit.py — GDD 退役术语扫描(半自动) python tools/doc_term_audit.py ... # 只扫指定文件 python tools/doc_term_audit.py --json # 机器可读 -口径:扫 design/gdd/ 与 design/art/ 两处文档域(2026-10-21 迭代 32 卡①反哺批扩面 art, -用户裁)——design/research(历史提案)、docs/(样例)与 production/ 不在扫描域; +口径:扫 design/gdd/ 与 design/art/ 两处文档域 + 四份根文件(`待办清单.md`/`体验验证清单.md`/ +`roadmap.md`/`AGENTS.md`,2026-10-21 迭代 32 卡①反哺批扩面,用户裁;根文件同属现行文本) +——design/research(历史提案)与 reports/(中间文档)不在扫描域; 词表扩充 = 改 RETIRED_TERMS(受 doc-conventions §4 词表冻结约束:唯一入口=用户实读反馈并经用户裁决)。 """ import argparse @@ -71,6 +72,10 @@ RETIRED_TERMS = [ ] DEFAULT_DIRS = ["design/gdd", "design/art"] +# 根规则与流程文件同属现行文本,2026-10-21 迭代 32 反哺批复测后纳入扫描面: +# 当日实测这批文件自身含 3 处用语表废止词(roadmap 的「对拍」「标旗」、AGENTS 的「收口」×2), +# 随同批订正后判红归零才扩面——先改现实、再让闸盯住现实,避免带红扩面。 +DEFAULT_FILES = ["待办清单.md", "体验验证清单.md", "roadmap.md", "AGENTS.md"] # 用语规范 A 表补充词专项补扫:随批/台账 两词本身是上方行级白名单信号(行内出现即归 # 留档类),主扫描对它们自豁免;本通道只做节外残留的专项报告,供后续触碰批清偿。 @@ -191,6 +196,7 @@ def main(): for d in DEFAULT_DIRS: paths += sorted(Path(d).rglob("*.md")) paths += sorted(Path(d).rglob("*.yaml")) + paths += [Path(f) for f in DEFAULT_FILES] paths = [p for p in paths if Path(p).exists()] findings = scan(paths) + scan_supplement(paths) diff --git a/tools/run_all_gates.sh b/tools/run_all_gates.sh index bd416d97..f094ab44 100644 --- a/tools/run_all_gates.sh +++ b/tools/run_all_gates.sh @@ -185,6 +185,9 @@ gate "07 doc_link" "doc_link.log" "$PY" "$REPO/tools/doc_link_audit.py" --strict gate "08 doc_term" "doc_term.log" "$PY" "$REPO/tools/doc_term_audit.py" --strict # ── 8c. 流水线闸(待办清单条目状态机+roadmap 迭代总表+一次交叉核,判据=doc-conventions §12)── gate "08c 流水线闸" "pipeline.log" "$PY" "$REPO/tools/pipeline_gate.py" +# 8d 引用可核(tools/doc_ref_audit.py,2026-10-21 交付)暂不注册:新闸件无基线记录必判「闸况变化」拦回执, +# 而建档要改 game/tests/.gates/baseline.json——触 game/ 即要求代码域全量测试(process-conventions §3.10 推域口径), +# 文档域批按测试两入口铁规零跑游戏测试。注册与建档随下一个触 game/ 的批次一并做(待办清单在册)。 fi # ── 6c. 回放确定性对拍(条件闸件;属代码域)── if in_domain code; then diff --git a/待办清单.md b/待办清单.md index a4185f2c..9e924cfd 100644 --- a/待办清单.md +++ b/待办清单.md @@ -513,9 +513,9 @@ 4. **迷雾对三关扩对**(iter19 卡②遗留):素材不入 git 致三关逐关 floor avg 实查受限,ui_contrast 迷雾测点现按在册单值 #453020;素材入库或授权读素材后,以 tools 脚本算三关逐关 avg→最亮者核合成(最坏情况判据契约 7 完整化)。**归属**:对比度探针面(前置=素材可读授权) 5. **字面量墨收测前置**(iter19 卡②遗留):bcard 属性描述/类型脚注/✓章/primary_button 字四处内联 Color8 无常量形态,收测需先在 ui_kit 立常量(呈现批顺路件,改 ui_kit 越当批面)。**归属**:呈现优化批(ui_kit 常量面) 6. **TG_* 装饰带非文字判据**(iter19 卡②遗留):卡顶类型色带为 8px Bayer 抖动装饰带(DitherBand),非文字;如需机检化(WCAG 1.4.11 非文字 3:1)另立探针段裁决。**归属**:对比度探针扩展段 -7. **数据配置.md:223 历史行死指 + 商店房截图纳屏**(iter19 卡①遗留):前者=v0.4 版本史行 backtick 指已退役探针(doc_link advisory 级不 FAIL,历史行不改写原则下留观,如需清零可下批 prose 化+补退役行);后者=商店房截图纳屏留后续呈现批(考证结论在 shot_probe 头注)。**归属**:文档卫生批/呈现批 +7. **商店房截图纳屏**(iter19 卡①遗留):商店房截图纳屏留后续呈现批(考证结论在 shot_probe 头注)。本项原并列的「`数据配置.md:223` 历史行死指」半句已于 2026-10-21 实查核销——禁写变更记录规约生效后该文件的版本史行整段已不存在(现全文 212 行,文内零版本史行),被指对象随之消亡。**归属**:呈现批 -**归属**:①熵增闸白名单 ②冒险结构/战斗开场参数面 ③⑤呈现优化批 ④⑥对比度探针面/扩展段 ⑦文档卫生批/呈现批——逐项见现状清单 +**归属**:①熵增闸白名单 ②冒险结构/战斗开场参数面 ③⑤呈现优化批 ④⑥对比度探针面/扩展段 ⑦呈现批——逐项见现状清单 **状态**:待写卡(备选) @@ -713,7 +713,7 @@ #### `game/` 域文档两处措辞订正欠账(2026-10-21 登记,来源=批次移交,设计面=工程直入) -**现状**:两处 `game/` 内文本与现实不符,改 `game/` 任何路径都会触发代码域全量测试(2026-10-20 用户裁「零代码批不改该行、登记欠账」),故不入本写入批:①`game/tests/static_scan.sh:100` S11 注释仍称「完美排雷」不在退役词对照表里——2026-10-21 起该词已入表(术语表退役词对照行在册),注释与 `:122` 追加行按「S11 权威=术语表解析」口径可一并订正;②`game/tests/README.md:58` 记「manifest 已登记实跑 26 套件」——迭代 32 卡② 后现况为 35 套件(含 counter_prefix_fatal 负面套件),以 `run_all.gd` 现况为准更新。 +**现状**:两处 `game/` 内文本与现实不符,改 `game/` 任何路径都会触发代码域全量测试(2026-10-20 用户裁「零代码批不改该行、登记欠账」),故不入本写入批:①`game/tests/static_scan.sh:100` S11 注释仍称「完美排雷」不在退役词对照表里——2026-10-21 起该词已入表(术语表退役词对照行在册),注释与 `:122` 追加行按「S11 权威=术语表解析」口径可一并订正;②`game/tests/README.md:58` 记「manifest 已登记实跑 26 套件」——迭代 32 卡② 后现况为 35 套件(含 counter_prefix_fatal 负面套件),以 `run_all.gd` 现况为准更新。同文件另两处 `design/qa/` 死指已另有在册条目(本清单「game/tests/README 分级表证据落点行仍指 design/qa/」),本条不重复登记。 **归属**:`game/tests/`(代码域,随下一个触碰 game/ 的批次顺带清) @@ -721,6 +721,16 @@ --- +#### 引用可核闸注册与建档欠账(2026-10-21 登记,来源=会话提及,设计面=工程直入) + +**现状**:新机检件 `tools/doc_ref_audit.py`(文档内「文件:行号」指针的存在性与行界核对,件头注即判据)已于 2026-10-21 交付并双向验证——注入不存在路径 EXIT=1、注入超界行号 EXIT=1、扫描面为空自判 FAIL、还原 EXIT=0(当日实测:63 件文档/81 处引用/红项 0/建议 6)。它**尚未注册进 `tools/run_all_gates.sh` 文档域**,原因=注册要把绿记录写进 `game/tests/.gates/baseline.json`(先例见 8f66ae15 之 08c 与 e8b6751b 之 06b),而改 `game/` 下任何路径都要求代码域回执、即跑全量游戏测试,文档域批按测试两入口铁规零跑(2026-10-20 用户裁「不为边际正确性付跑测成本」)。同批附带交付:`tools/doc_term_audit.py` 扫描面已扩到四份根文件(待办清单/体验验证清单/roadmap/AGENTS),扩面实测「疑似现行」0 处、变异注入见红 EXIT=1 还原 EXIT=0。内容锚核对(`--anchors`)实测 81 处引用出 58 条未命中,噪声约七成,按建议级交付不判红,待真实批次积累后再定是否收紧。 + +**归属**:`tools/run_all_gates.sh` 注册行+`game/tests/.gates/baseline.json` 建档(代码域批次顺带) + +**状态**:待写卡 + +--- + #### 迭代 32 移交项一——奇物门票三处玩家文案待定性后传导(2026-10-21 登记,来源=批次移交,设计面=文档轨) **现状**:「门票(专长门票)→专长凭证」已在 [术语表](design/gdd/术语表.md) 「退役词对照」在册;迭代 32 卡① 清了 `game/` 注释面的 36 处,但下列三处是**数据值与玩家可见文案**、属 奇物/专长 归类表述,需文档侧先定性才动,故本批只移交不改:①`game/data/tables/shop.tres:86` `"display_name": "奇物门票"`;②③`game/presentation/curio_interact_controller.gd:165`/`:166` 交互文案「奇物门票/选定即开一次奇物三选一」。代码闸拦不到它们——S11 只取注释面(.gd 取 # 后、.tres 取 ; 后),数据值与 UI 文案不在其扫描语义内。关联文档:[奇物](design/gdd/systems/冒险循环/奇物.md)(归类口径 owner,现行版本以文首状态行为准)。用户 2026-10-21 裁=与本清单「2026-10-18 冒记案遗留待裁两项」第②项(资源成员判据句)同源,待该项裁决后走传导批。 @@ -742,3 +752,6 @@ **归属**:design/gdd/ 各件(机制表述面)+ design/gdd/术语表.md(口径与除外注) **状态**:待文档设计 + + + From b28a1bb7c04b6ac5570a4ec1efc937612a1cfdf3 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 05:51:32 +0800 Subject: [PATCH 56/59] =?UTF-8?q?chore(=E5=8F=98=E5=BC=82=E6=AE=8B?= =?UTF-8?q?=E7=95=99=E6=B8=85=E5=87=80):=2001-=E6=A0=B8=E5=BF=83=E5=BE=AA?= =?UTF-8?q?=E7=8E=AF.md=20=E6=81=A2=E5=A4=8D=E5=8E=9F=E5=AD=97=E8=8A=82?= =?UTF-8?q?=E2=80=94=E2=80=94=E6=9C=BA=E6=A3=80=E5=8F=98=E5=BC=82=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E4=B8=B4=E6=97=B6=E6=B3=A8=E5=85=A5=E7=9A=84=E8=A1=8C?= =?UTF-8?q?=E5=B7=B2=E5=88=A0=E4=BD=86=E5=A4=9A=E7=95=99=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E5=B0=BE=E7=A9=BA=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/gdd/01-核心循环.md | 1 - 1 file changed, 1 deletion(-) diff --git a/design/gdd/01-核心循环.md b/design/gdd/01-核心循环.md index eab7ea80..124f3178 100644 --- a/design/gdd/01-核心循环.md +++ b/design/gdd/01-核心循环.md @@ -160,4 +160,3 @@ **获取概率提升**是元进度/营地的合法提升轴(可提升=奇物高档位出现率/秘宝解锁进度/地图 T3/T4 权重),但**不动保底**——保底是承诺不是概率,禁止任何概率件改变 T3「每板必有回复」类承诺。 **专长 rarity 语义约束**:Boss 三选一候选按档配比或加权抽取,使罕见度对出现率生效(字段双脱钩修复——此前 rarity 不影响抽选也不稳代表幅度);具体配比归调参批。 - From cbe4b4a825ffa85597f58cbc89b02b6aa14c48b9 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 06:49:05 +0800 Subject: [PATCH 57/59] =?UTF-8?q?docs(Alpha=E5=87=BA=E5=8F=A3=E8=A3=81?= =?UTF-8?q?=E5=86=B3):=2008=20v1.11=20=E5=86=99=E5=85=A5=E4=BA=94=E9=A1=B9?= =?UTF-8?q?=E5=BE=85=E8=A3=81=E4=B8=8E=20B/C=20=E5=87=BA=E5=8F=A3=E5=88=A4?= =?UTF-8?q?=E6=8D=AE=EF=BC=8C=E6=9C=AA=E5=86=B3=E9=A1=B9=E6=B8=85=E9=9B=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 战斗表现按现有呈现语义判在役,正式演出设计与资产终稿排 Beta - 生涯期二、期三全部排 Beta,Alpha 只保留期一;非玩法面不新增内容 - 第四关、素材升档重产、营地与元进度件贴图排 Beta - 站桩帧动画列入 Alpha 定版前置清单;战斗一屏样张列为 Alpha 硬前置 - 关卡节点图生成现状订正为待做;棋盘观感与样张的旧迭代注记清除 - 待办清单同步生涯、站桩、升档、UI 贴图、样张、立绘、棋盘观感条目 --- design/gdd/08-Alpha版本标准.md | 45 +++++++++++++++------------------- 待办清单.md | 24 +++++++++--------- 2 files changed, 32 insertions(+), 37 deletions(-) diff --git a/design/gdd/08-Alpha版本标准.md b/design/gdd/08-Alpha版本标准.md index 3d1bc3ef..3bc7d7e8 100644 --- a/design/gdd/08-Alpha版本标准.md +++ b/design/gdd/08-Alpha版本标准.md @@ -2,7 +2,7 @@ > **一句话定位**:本文定义这个项目的 **Alpha 版本包含哪些东西**——它是里程碑 M3 的完成标准,也是判断"还差什么"的对照表。 > **本文只列条目,不写内容**:每样东西是什么、规则怎么走,一律归各自的权威文档,本文只给指路链接。想知道某样东西的定义,请点链接,不要在本文里找解释。 -> **状态**:**已定稿(v1.10)**——2026-10-13 用户令定稿,此后十次升版的明细见 git 提交史。Alpha 的内容范围自此冻结:增删条目一律须经用户裁决。 +> **状态**:**已定稿(v1.11)**——2026-10-13 用户令定稿,此后十一次升版的明细见 git 提交史。Alpha 的内容范围自此冻结:增删条目一律须经用户裁决。 > **成文**:2026-10-13。 ## 本文怎么用 @@ -20,6 +20,8 @@ 四个循环下的全部子系统。分界与职责见 [02-系统清单](02-系统清单.md),本文不重复。 +Alpha 内只推进玩法循环本身的内容与表现(棋盘、关卡、战斗);跨局循环等非玩法面不新增内容,新内容排 Beta。 + ### 排雷循环 | 条目 | 事实源 | 现状 | @@ -37,7 +39,7 @@ | 敌人系统 | [敌人系统](systems/战斗循环/敌人系统.md) | 在役 | | 增益状态 | [增益状态](systems/战斗循环/增益状态.md) | 在役 | | 地图战斗资源(格面资源) | [地图战斗资源](systems/战斗循环/地图战斗资源.md) | 在役 | -| 战斗表现(动画与演出) | [战斗表现](systems/战斗循环/战斗表现.md) | 待裁 | +| 战斗表现(动画与演出) | [战斗表现](systems/战斗循环/战斗表现.md) | 在役(Alpha 判据=受击闪白/死亡不瞬间消失/高光行/逐行排播四条可读;正式演出设计与资产终稿排 Beta,不属 Alpha 完成判据) | ### 冒险循环 @@ -45,8 +47,8 @@ |---|---|---| | 冒险结构 | [冒险结构](systems/冒险循环/冒险结构.md) | 在役 | | 关卡节点地图 | [关卡节点地图](systems/冒险循环/关卡节点地图.md) | 在役(待重构,见下一条) | -| 关卡节点图重构(增加可选节点) | [关卡节点地图](systems/冒险循环/关卡节点地图.md)+[关卡节点图生成](systems/冒险循环/关卡节点图生成.md) | 待做(文档设计已闭合,待写卡) | -| 关卡节点图生成 | 参数化长图:产出规格与生成参数 | 在役(v1.0 重写完成,与上一条同批实施) | +| 关卡节点图重构(增加可选节点) | [关卡节点地图](systems/冒险循环/关卡节点地图.md)+[关卡节点图生成](systems/冒险循环/关卡节点图生成.md) | 待做(文档设计已闭合,待写卡;单独成批,2 周时间盒;优先全量 v2.0,第一周结束若多终点与地图屏明显超载则分两步:先三关基础分叉+单终点可玩;出口判据见两份文档的验收标准,另加旧模板清理与真人目检选路有取舍) | +| 关卡节点图生成 | 参数化长图:产出规格与生成参数 | 待做(规格 v1.0 已定稿;生成器实现与上一条同一批) | | 难度曲线与 Boss | [难度曲线与Boss](systems/冒险循环/难度曲线与Boss.md) | 在役 | | 奇物 | [奇物](systems/冒险循环/奇物.md) | 在役 | @@ -58,7 +60,7 @@ | 天赋树 | [天赋树](systems/跨局循环/天赋树.md) | 在役 | | 秘宝 | [秘宝](systems/跨局循环/秘宝.md) | 在役 | | 锻造工坊 | [锻造工坊](systems/跨局循环/锻造工坊.md) | 在役(实装批 2026-10-12 入库;满级特效按 2026-10-12 裁 6 留扩展位、本期不做,不碍在役判定) | -| 生涯 | [生涯](systems/跨局循环/生涯.md) | 在役(期一;期二、期三待裁) | +| 生涯 | [生涯](systems/跨局循环/生涯.md) | 在役(期一;期二、期三排 Beta,不属 Alpha) | ### 表现与支撑 @@ -91,7 +93,6 @@ | 天赋树节点集 | `meta_tree.tres` | 在役 | | 锻造工坊路线行族 | `forge.tres` | 在役(定价 provisional 归 M4;表名订正与入库依据见 git 提交史) | | 混编遭遇行集 | `enemy.tres` | 在役(首批;第二批移挂 Beta,裁决与明细见 git 提交史) | -| 第四关 | —— | 待裁 | --- @@ -101,7 +102,7 @@ |---|---|---| | 主菜单 | —— | 在役 | | 开始覆盖层 | —— | 在役 | -| 营地(天赋树 / 锻造工坊 / 秘宝匣 / 图鉴) | [camp](ux/camp.md) | 在役(锻造柜台占位面板注已解除;柜台贴图占位归「五 · 表现」UI 贴图重构批行) | +| 营地(天赋树 / 锻造工坊 / 秘宝匣 / 图鉴) | [camp](ux/camp.md) | 在役(锻造柜台占位面板注已解除;柜台贴图占位排 Beta,不碍在役判定) | | 生涯页 | [生涯](systems/跨局循环/生涯.md) | 在役(期一) | | 关卡地图屏 | [level-map](ux/level-map.md) | 在役 | | 战斗屏 | [battle](ux/battle.md) | 在役 | @@ -109,7 +110,7 @@ | 关卡结算屏 | [level-clear](ux/level-clear.md) | 在役 | | 三选一(奖励节点 / 通关) | [node-reward](ux/node-reward.md) | 在役 | | 商店 | [shop](ux/shop.md) | 在役 | -| 状态面板(局内) | [待办清单](../../待办清单.md) | 部分在役(在役半=面板本体——迭代 17 卡③实装、2026-10-13 由「暂停层」改名;未结半=2026-10-16 用户令瘦身——去跨关解锁内容〔秘宝匣解锁态 12 行概览 / 天赋树已购概览〕、只留本局五件〔带的秘宝 / 已获专长 / 当前属性 / 现有 GP / 钥石总量〕;登记面=待办清单「状态面板瘦身」专条) | +| 状态面板(局内) | [待办清单](../../待办清单.md) | 部分在役(在役半=面板本体——迭代 17 卡③实装、2026-10-13 由「暂停层」改名;未结半=2026-10-16 用户令瘦身——去跨关解锁内容〔秘宝匣解锁态 12 行概览 / 天赋树已购概览〕、只留本局五件〔带的秘宝 / 已获专长 / 当前属性 / 现有 GP / 钥石总量〕;登记面=待办清单「状态面板瘦身」专条;出口判据=只显示本局五件、两段跨关解锁退役、文案更新、界面探针或断言覆盖、用户目检通过) | | 冒险终局面板 | —— | 在役 | | 图例面板 | —— | 在役 | | 设置面 | [设置与本地化](systems/表现与支撑/设置与本地化.md) | 在役 | @@ -143,21 +144,19 @@ | 像素美术风格与色板 | [美术圣经](../art/art-bible.md) | 在役 | | 棋盘瓦片与格面资源图标 | [美术圣经](../art/art-bible.md) | 在役 | | 未开格类型微光(五组色相+明度档) | [HUD框架](systems/表现与支撑/HUD框架.md) | 在役(明度档 provisional 值登记见 art-bible 的 git 提交史,复核转正归战斗一屏样张) | -| 棋盘观感(第二 / 三关亮度与对比度) | [待办清单](../../待办清单.md) | 待做(2026-10-16 用户令编入迭代 30,序位③) | -| 立绘清晰度回退评估(是否改用高清图) | [角色设计](../art/character-design.md) | 待做(评估已结——2026-10-14 用户裁维持像素风、升级精细手绘像素、不回退高清图,裁决录=[美术审计-cursor会话存档](../research/美术审计-cursor会话存档-2026-10-14.md) §2.2;余=立绘按新口径重产+大小比例子题用户复核) | +| 棋盘观感(第二 / 三关亮度与对比度) | [待办清单](../../待办清单.md) | 待做(先做素材轴/UI 轴对照截图定性,再按定轴修复;出口=用户实机目检第二、三关不再判「看着费劲」) | +| 立绘清晰度回退评估(是否改用高清图) | [角色设计](../art/character-design.md) | 待做(评估已结——2026-10-14 用户裁维持像素风、升级精细手绘像素、不回退高清图,裁决录=[美术审计-cursor会话存档](../research/美术审计-cursor会话存档-2026-10-14.md) §2.2;Alpha 范围=主角+三个 Boss 按新口径重产,其余敌种当前可读则保留到 Beta;出口=用户目检八敌体量关系通过且主角与三个 Boss 重产完成) | | 敌人立绘(全敌种) | [角色设计](../art/character-design.md) | 在役 | | 主角立绘三态 | [角色设计](../art/character-design.md) | 在役 | | 状态图标 | [美术圣经](../art/art-bible.md) | 在役 | | 战斗演出链(弹道 / 受击 / 血条 / 灰化) | [战斗表现](systems/战斗循环/战斗表现.md) | 在役 | | 逐行结算排播 | [settlement-summary](ux/settlement-summary.md) | 在役 | | 减动效开关 | [设置与本地化](systems/表现与支撑/设置与本地化.md) | 在役 | -| 站桩帧动画 | [待办清单](../../待办清单.md) | 待裁 | -| 素材升档重产 | [待办清单](../../待办清单.md) | 待裁 | +| 站桩帧动画 | [待办清单](../../待办清单.md) | 待做(列入 Alpha 定版前置清单:定版前完成最小版,路线预选拆件驱动;未完成则顺延 Beta;不占功能迭代) | | 全局纹理过滤设为邻近采样 | [待办清单](../../待办清单.md) | 在役(迭代 26 · 2026-10-14 入库:default_texture_filter=0+平滑渐变件三处显式 LINEAR 白名单,翻转面全枚举闭合) | -| UI 贴图重构批(营地与元进度件出终稿) | [美术资产清单](../art/art-assets-checklist.md) | 待做 | -| UI 字体补完(拉丁像素字专件 + 字重两档) | [美术圣经](../art/art-bible.md) §7.4 | 待做 | -| 战斗一屏样张(界面美术的终稿闸) | [美术圣经](../art/art-bible.md) §1.4 | 待做(2026-10-16 用户令编入迭代 30,序位②) | -| UI 氛围层与九宫格切片观感修 | [待办清单](../../待办清单.md) | 部分在役(迭代 26 · 2026-10-14:光柱硬边半已修=连续 alpha 渐变;九宫格切片错位半未结——待素材尺寸核对,属美术线连带面) | +| UI 字体补完(拉丁像素字专件 + 字重两档) | [美术圣经](../art/art-bible.md) §7.4 | 待做(Alpha 只做标题/正文层级调整:字号档差+墨色深浅;正式拉丁像素字专件与第二字重排 Beta) | +| 战斗一屏样张(界面美术的终稿闸) | [美术圣经](../art/art-bible.md) §1.4 | 待做(Alpha 硬前置:站桩帧动画的定版前置与主角+三 Boss 重产都依赖它;出口=用户目检通过的战斗屏样张,并产出尺寸档/色板/明度档清单) | +| UI 氛围层与九宫格切片观感修 | [待办清单](../../待办清单.md) | 部分在役(光柱硬边已修=连续 alpha 渐变;未结半=九宫格切片错位——Alpha 内做最小修复:核对素材尺寸,必要时重出九宫格素材,全套素材重出排 Beta;出口=结算屏与图例屏错位消失,渲染闸+用户目检通过) | | UI 元素细节修(滑轨填充 / 图标垫块 / 留白 / 开发件外泄) | [待办清单](../../待办清单.md) | 在役(迭代 26 · 2026-10-14 入库:①滑轨填充随迭代 25 注销;余②图标垫块明度差降档/③商店+营地布局修/④诊断钮迁调试浮窗 全落地) | --- @@ -193,19 +192,15 @@ | 数值统一标定(M4 数值批) | 2026-10-09 里程碑立规:M4 = Beta 阶段、M3 未由用户明令关闭前不排期(用户 2026-10-07 令移出迭代 18;2026-10-16 确认此裁长期有效)——待办清单各条「已编入 Alpha 收官 M4」措辞系旧口径残留 | | 连刷 / 换图资金跨战斗携带 | [05-不做清单](05-不做清单.md) | | 战斗节点地图类型差异化(更多地图主题) | 排 Beta 版本([playnote](../research/playnote.md),2026-10-13 裁) | +| 第四关 | 排 Beta;全库无设计承载,N>3 走扩展批流程([03-内容规模](03-内容规模.md)) | +| 生涯期二(历史冒险回看)与期三(图鉴) | 排 Beta;Alpha 只保留期一([生涯](systems/跨局循环/生涯.md)) | +| 素材升档重产 | 排 Beta;原始动机已由八敌逐键定档解决,剩余提灯候选随 Beta 资产批重议([待办清单](../../待办清单.md)) | +| UI 贴图重构(营地与元进度件终稿) | 排 Beta;营地柜台与元进度图标在 Alpha 保留占位,不碍在役判定([美术资产清单](../art/art-assets-checklist.md)) | --- ## 七、未决项 -下面这些**要不要进 Alpha 还没定**,按上面的表逐条对应。每一项都需要用户裁定「进 / 不进 / 换成什么」,裁定后填回对应表格的现状列,本节的该行随即删除。 - -| # | 未决项 | 出现在 | -|---|---|---| -| 1 | 战斗表现(动画与演出)算不算已经达标 | 一 · 战斗循环 | -| 2 | 生涯页期二(历史冒险回看)与期三(图鉴承接)进不进 Alpha | 一 · 跨局循环 | -| 3 | 第四关进不进 Alpha | 二 · 内容量 | -| 4 | 站桩帧动画进不进 Alpha | 五 · 表现 | -| 5 | 素材升档重产进不进 Alpha | 五 · 表现 | +无。 --- diff --git a/待办清单.md b/待办清单.md index 9e924cfd..5394e4ed 100644 --- a/待办清单.md +++ b/待办清单.md @@ -12,13 +12,13 @@ #### UI 贴图重构批——营地与元进度件仍是程序化占位(2026-10-13 登记,来源=审计发现,设计面=美术轨) -**现状**:营地的柜台场景贴图目前是程序化画出来的临时形态,没有上贴图。这条债原先只写在美术侧的资产清单里([美术资产清单](design/art/art-assets-checklist.md) 第 134 行与第 175 行,原文注明"营地现为程序化占位,状态记录 121⑧ 口径,排期归 UI 贴图重构批"),2026-10-13 由 UI 美化三层诊断转立本清单专条。规格其实已经定了——烛光黄 `#F6C667` 配木色 `#8A5A34`(见 [美术圣经](design/art/art-bible.md) §4.4),素材来源允许走"通用图标改色复用"这条低成本渠道。 +**现状**:营地的柜台场景贴图目前是程序化画出来的临时形态,没有上贴图。这条债原先只写在美术侧的资产清单里([美术资产清单](design/art/art-assets-checklist.md) 第 134 行与第 175 行,原文注明"营地现为程序化占位,状态记录 121⑧ 口径,排期归 UI 贴图重构批"),2026-10-13 由 UI 美化三层诊断转立本清单专条。规格其实已经定了——烛光黄 `#F6C667` 配木色 `#8A5A34`(见 [美术圣经](design/art/art-bible.md) §4.4),素材来源允许走"通用图标改色复用"这条低成本渠道。Alpha 出口裁决:不进 Alpha,排 Beta——营地与元进度件贴图在玩法循环之外,Alpha 保留占位。 **缺口**:还差一次「自己画 vs 找 CC0 素材改色」的美术裁决(见 [美术资产清单](design/art/art-assets-checklist.md) §0 的复用渠道闸),裁决后才能定素材工单写卡。 **归属**:UI 贴图重构批(美术线;须先裁决是自己画还是找 CC0 素材改色,两条备选见 [美术资产清单](design/art/art-assets-checklist.md) §0 的复用渠道闸) -**状态**:待美术设计 +**状态**:待美术设计(备选) #### UI 字体补完——缺拉丁像素字专件、且全局只有一个字重(2026-10-13 登记,来源=审计发现,设计面=美术轨) @@ -32,7 +32,7 @@ #### 战斗一屏样张 P0 未开工——界面成品是否过审的那把尺子还没建(2026-10-13 登记,来源=审计发现,设计面=美术轨) -**现状**:[美术圣经](design/art/art-bible.md) §7.1 明文写着"程序化占位=临时态,任何屏的终稿闸=§1.4 整屏样张过闸;占位态禁止跨里程碑"。而 [美术素材状态清单](design/art/art-status-checklist.md) 把「战斗一屏样张」这件最高优先级的素材标的是**未开始**——也就是说,**判定界面美术算不算过关的那把尺子到现在还没造出来**。2026-10-16 曾编入迭代 30 卡②(UI 呈现三卡批序位②),2026-10-17 用户裁定不满足「迭代=代码实现批」的开发条件、剔除回待设计(理由=样张交付物本身就是设计规格,正式字体与素材均未定稿;同日样张批开工已被用户终止)。v1.4 旧卡留 reports/需求卡片-战斗一屏样张批-2026-10-16.md 作素材,非已写卡状态,重启不得直接开工。 +**现状**:[美术圣经](design/art/art-bible.md) §7.1 明文写着"程序化占位=临时态,任何屏的终稿闸=§1.4 整屏样张过闸;占位态禁止跨里程碑"。而 [美术素材状态清单](design/art/art-status-checklist.md) 把「战斗一屏样张」这件最高优先级的素材标的是**未开始**——也就是说,**判定界面美术算不算过关的那把尺子到现在还没造出来**。2026-10-16 曾编入迭代 30 卡②(UI 呈现三卡批序位②),2026-10-17 用户裁定不满足「迭代=代码实现批」的开发条件、剔除回待设计(理由=样张交付物本身就是设计规格,正式字体与素材均未定稿;同日样张批开工已被用户终止)。v1.4 旧卡留 reports/需求卡片-战斗一屏样张批-2026-10-16.md 作素材,非已写卡状态,重启不得直接开工。Alpha 出口裁决:列入 Alpha 硬前置——站桩帧动画的定版前置与主角+三 Boss 重产都依赖它。 **缺口**:还差「设计讨论→需求澄清→美术定稿」一轮设计(样张即设计目标图,产出尺寸档/色板/明度档清单反向给素材批),定稿后重新立卡方可开发。 @@ -331,7 +331,7 @@ #### 第二 / 三关棋盘观感——亮度与对比度(2026-10-13 登记,来源=playnote,设计面=双轨) -**现状**:来源=playnote 用户试玩记录「UI 优化,第二第三关的棋盘看着太累了;不知道是因为亮度还是对比度的原因,看着非常费劲,非常不舒服」。2026-10-13 用户裁定:**这是需要做的**,且本就属版本标准的覆盖范围——[08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「五 · 表现」已新增「棋盘观感(第二 / 三关亮度与对比度)」行,标待做。**开工前须先定性(沿用既有裁决)**:是**素材轴**问题(棋盘瓦片与格面图标本身的明度与色相),还是 **UI 轴**问题(舞台底色与叠加层的对比关系)——两轴修法完全不同,定性错了等于白改一轮;该定性要求(原备忘 (e) 项)是本条的开工前置。2026-10-16 曾编入迭代 30 卡③(UI 呈现三卡批序位③),2026-10-17 用户裁定剔除回待设计(自身挂「素材轴/UI 轴」定性人闸+甲/乙〔recolor/远程生图重产〕素材裁点;若裁乙,其瓦片规格依赖战斗一屏样张批的目标规格清单产出)。v1.4 旧卡留 reports/需求卡片-二三关棋盘观感批-2026-10-16.md 作素材,非已写卡状态。与已完成注销的「呈现层残余 <4.5:1 文字位」分工:本条管**棋盘区域整体的观感**(亮度/对比度/费劲感,体感问题),彼条管**具体文字位的对比度读数**(机检可判硬指标),两条不同面不互相替代。 +**现状**:来源=playnote 用户试玩记录「UI 优化,第二第三关的棋盘看着太累了;不知道是因为亮度还是对比度的原因,看着非常费劲,非常不舒服」。2026-10-13 用户裁定:**这是需要做的**,且本就属版本标准的覆盖范围——[08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「五 · 表现」已新增「棋盘观感(第二 / 三关亮度与对比度)」行,标待做。**开工前须先定性(沿用既有裁决)**:是**素材轴**问题(棋盘瓦片与格面图标本身的明度与色相),还是 **UI 轴**问题(舞台底色与叠加层的对比关系)——两轴修法完全不同,定性错了等于白改一轮;该定性要求(原备忘 (e) 项)是本条的开工前置。2026-10-16 曾编入迭代 30 卡③(UI 呈现三卡批序位③),2026-10-17 用户裁定剔除回待设计(自身挂「素材轴/UI 轴」定性人闸+甲/乙〔recolor/远程生图重产〕素材裁点;若裁乙,其瓦片规格依赖战斗一屏样张批的目标规格清单产出)。v1.4 旧卡留 reports/需求卡片-二三关棋盘观感批-2026-10-16.md 作素材,非已写卡状态。与已完成注销的「呈现层残余 <4.5:1 文字位」分工:本条管**棋盘区域整体的观感**(亮度/对比度/费劲感,体感问题),彼条管**具体文字位的对比度读数**(机检可判硬指标),两条不同面不互相替代。Alpha 出口裁决:Alpha 必须,先做素材轴/UI 轴对照定性;出口=用户实机目检不再判「看着费劲」。 **缺口**:还差「素材轴 / UI 轴」定性设计讨论与甲/乙素材裁点裁决;素材轴若走重产,还依赖战斗一屏样张批的目标规格清单产出。 @@ -351,7 +351,7 @@ #### 资产升档重产批(art-bible v3.0 中修挂账③,2026-09-29 登记,来源=批次移交,设计面=美术轨) -**现状**:v3.0 §8.2 档位上调方向候选(主角立绘 48×72→64×96 档、敌立绘三档上调评估)**已实质完成**——2026-10-06 art-bible v3.7 八敌逐键定档(源档 36–94、显示 ×2 整数;派生管线=pixel-1 紧裁→等比缩至档高→dom_block_resize)取代 64/96/128 升档路线;存在感问题改经方案二(B 区 270 / 立绘显示上限 188 / 血条状态落底排)解决,不再走升档路线。裁决史:2026-09-30 迭代 9 三裁决案乙(本迭代不升档,先收 Alpha 真人读数再定;A4 尺寸基线冻结〔立绘 46×48/小人源 32×32〕维持有效);2026-10-04 用户令暂不做、先忽略;2026-10-06 用户令优先级再降(维持挂起;同日 playnote 立绘批评已由「立绘逐键定档批」承接兑现)。**剩余挂起项=提灯点亮解禁候选**(character-design 提灯,v3.0 明度分层允许空间光照),重启=用户点名或 M-4 升档批。 +**现状**:v3.0 §8.2 档位上调方向候选(主角立绘 48×72→64×96 档、敌立绘三档上调评估)**已实质完成**——2026-10-06 art-bible v3.7 八敌逐键定档(源档 36–94、显示 ×2 整数;派生管线=pixel-1 紧裁→等比缩至档高→dom_block_resize)取代 64/96/128 升档路线;存在感问题改经方案二(B 区 270 / 立绘显示上限 188 / 血条状态落底排)解决,不再走升档路线。裁决史:2026-09-30 迭代 9 三裁决案乙(本迭代不升档,先收 Alpha 真人读数再定;A4 尺寸基线冻结〔立绘 46×48/小人源 32×32〕维持有效);2026-10-04 用户令暂不做、先忽略;2026-10-06 用户令优先级再降(维持挂起;同日 playnote 立绘批评已由「立绘逐键定档批」承接兑现)。**剩余挂起项=提灯点亮解禁候选**(character-design 提灯,v3.0 明度分层允许空间光照),重启=用户点名或 M-4 升档批。Alpha 出口裁决:不进 Alpha,排 Beta;提灯候选随 Beta 资产批重议。 **缺口**:还差提灯点亮解禁候选的重议设计(升档批或用户点名触发时一并裁)。 @@ -361,7 +361,7 @@ #### 立绘清晰度回退评估——是否改用高清图(2026-10-13 登记,来源=playnote,设计面=美术轨) -**现状**:来源=playnote 用户试玩记录「现在的立绘太丑了,像素化的粒度太低了,导致根本看不清立绘;看是否可以改回用较为高清的图片?还有一个问题是大小的问题……现在地精的图片看起来比熊地精还要大,这并不合理」。2026-10-13 用户裁定:与「第二 / 三关棋盘观感」同属**美术线更新**。**两个子问题现状不同**:子问题一=怪物大小比例不合理——**已兑现**(体量语义改生物体型〔character-design §5.2,弃强度线性映射〕+八敌逐键定档〔art-bible §8.2〕),剩余面=用户是否复核验收;子问题二=像素粒度过低/是否改回高清图——**方向已裁(2026-10-14 用户裁)**:「还是像素风格立绘,但是不需要像现在太过于像素」,定性为**精细手绘像素**(不是插画、不是 HD-2D、不回退高清图;裁决录=[美术审计-cursor会话存档](design/research/美术审计-cursor会话存档-2026-10-14.md) §2.2;权威面 art-bible/character-design 口径节反哺另批),粒度问题已改派生管线(八敌源档 36–94 全过可读门槛:24 糊/32 可读/48 清楚)。[08-Alpha版本标准](design/gdd/08-Alpha版本标准.md) 未决项已随裁删除(2026-10-16 状态刷新批)。 +**现状**:来源=playnote 用户试玩记录「现在的立绘太丑了,像素化的粒度太低了,导致根本看不清立绘;看是否可以改回用较为高清的图片?还有一个问题是大小的问题……现在地精的图片看起来比熊地精还要大,这并不合理」。2026-10-13 用户裁定:与「第二 / 三关棋盘观感」同属**美术线更新**。**两个子问题现状不同**:子问题一=怪物大小比例不合理——**已兑现**(体量语义改生物体型〔character-design §5.2,弃强度线性映射〕+八敌逐键定档〔art-bible §8.2〕),剩余面=用户是否复核验收;子问题二=像素粒度过低/是否改回高清图——**方向已裁(2026-10-14 用户裁)**:「还是像素风格立绘,但是不需要像现在太过于像素」,定性为**精细手绘像素**(不是插画、不是 HD-2D、不回退高清图;裁决录=[美术审计-cursor会话存档](design/research/美术审计-cursor会话存档-2026-10-14.md) §2.2;权威面 art-bible/character-design 口径节反哺另批),粒度问题已改派生管线(八敌源档 36–94 全过可读门槛:24 糊/32 可读/48 清楚)。[08-Alpha版本标准](design/gdd/08-Alpha版本标准.md) 未决项已随裁删除(2026-10-16 状态刷新批)。Alpha 出口裁决:Alpha 范围=主角+三个 Boss 按新口径重产,其余敌种当前可读则保留到 Beta。 **缺口**:还差立绘按「精细手绘像素」新口径重产的设计——整屏方向稿与地面/立绘密度同批锁(与战斗一屏样张批联动)后才可出重产工单。 @@ -371,13 +371,13 @@ #### 站桩帧动画——Alpha 定版闸前完成(2026-10-06 登记,来源=审计发现,设计面=美术轨) -**现状**:审计报告 P0-3——定稿立绘零帧动画;现行动画全部程序化(死亡碎裂/受击闪白/意图徽标弹入=程序 tween,非帧资产)。用户裁定**动画是较往后的优化,Alpha 版本定版时间点之前完成即可**——当前 Alpha 开发期达成「看上去可游玩」即可。路线未拍板,审计报告三路线供重启时裁决:①**拆件驱动**(报告推荐:定稿立绘切部件〔头/躯干/臂/腿/武器〕+ 节点层级 tween 驱动——零身份漂移、帧数无限、内存小;项目已有先例=shovel_swing 三帧 + 程序化死亡碎裂)②AI 关键姿势 + 人工修 + 程序补帧 ③全 AI 逐帧(不推荐:身份漂移/像素抖动)。前置依赖=「立绘→派生形态」管线(等比整数缩放 + 降色 ≤32 + 脚底基线对齐 + 命名合规)——该管线同时是棋盘小人重出与八敌档位重算的前提。 +**现状**:审计报告 P0-3——定稿立绘零帧动画;现行动画全部程序化(死亡碎裂/受击闪白/意图徽标弹入=程序 tween,非帧资产)。用户裁定**动画是较往后的优化,Alpha 版本定版时间点之前完成即可**——当前 Alpha 开发期达成「看上去可游玩」即可。路线未拍板,审计报告三路线供重启时裁决:①**拆件驱动**(报告推荐:定稿立绘切部件〔头/躯干/臂/腿/武器〕+ 节点层级 tween 驱动——零身份漂移、帧数无限、内存小;项目已有先例=shovel_swing 三帧 + 程序化死亡碎裂)②AI 关键姿势 + 人工修 + 程序补帧 ③全 AI 逐帧(不推荐:身份漂移/像素抖动)。前置依赖=「立绘→派生形态」管线(等比整数缩放 + 降色 ≤32 + 脚底基线对齐 + 命名合规)——该管线同时是棋盘小人重出与八敌档位重算的前提。Alpha 出口裁决:列入 Alpha 定版前置清单——定版前完成最小版,路线预选拆件驱动;未完成则顺延 Beta,不占功能迭代。 -**缺口**:还差重启时(重启闸=Alpha 定版批)的路线拍板——先拍三路线之一,再立帧数规格与资产工单。 +**缺口**:还差 Alpha 定版批的路线正式拍板(预选拆件驱动)——拍板后立帧数规格与资产工单。 **归属**:[art-bible](design/art/art-bible.md) §8.4 帧数规格 · 战斗表现批 -**状态**:待美术设计(备选) +**状态**:待美术设计 #### 主角描边素材侧复核(2026-10-06 登记,来源=会话提及,设计面=美术轨) @@ -475,13 +475,13 @@ #### 「生涯」界面——冒险中数据回看的唯一承接处(2026-10-04 登记,来源=会话提及,设计面=文档轨) -**现状**:2026-10-04 用户裁决(UI 落码计划 P-C7)——冒险中不给数据回看:settlement_review_overlay(结算明细回看)与结算框「明细回看」钮在冒险中退役,战报带只留单行「上轮」;历史战报/结算明细的查看去向=新「生涯」界面(跨局汇总/历史冒险回看/图鉴承接)。来源=UI 重设计原型 v2 落码计划裁决记录(已退役,git 历史可查 §七)。**设计提纲已成文**:[systems/跨局循环/生涯.md](design/gdd/systems/跨局循环/生涯.md) v0.1 范围草案五节成文〔信息架构/承载内容清单/与既有界面关系/分期实装建议/待裁点〕,P0-P5 六裁点已全裁并写入文档〔P0甲 提纲落现行事实源 / P1甲 主菜单一级入口 / P2甲 每局一行摘要+cap 扩容 N+补用时埋点 / P3甲 敌人图鉴优先 / P4甲 局内不放入口+生涯零跳转 / P5甲 settlement_review 复活承接〕。**期一已落地**(2026-10-07 迭代 18 卡④实装批:生涯页六类九项+主菜单入口+终身计数域存档 v6,批末重闸全绿;实机人闸=体验验证清单⑲ 生涯页目检节)。剩余面=期二(历史回看/图鉴)与期三实装+P6 营地最近冒险条带去留(新发现待裁点,随提纲评审一并裁)。**迭代 19 卡②遗留件(2026-10-08 登记)**:settlement_review_overlay.gd 现态考证=未接线遗留件(全仓零引用,M9 结算框改版「明细回看」钮退役后遗留)——处置两途:①随生涯实装批按 P5 甲复活承接(重接线入生涯);②确认不再需要则正式退役删除文件;二选一归生涯实装批/用户裁。 +**现状**:2026-10-04 用户裁决(UI 落码计划 P-C7)——冒险中不给数据回看:settlement_review_overlay(结算明细回看)与结算框「明细回看」钮在冒险中退役,战报带只留单行「上轮」;历史战报/结算明细的查看去向=新「生涯」界面(跨局汇总/历史冒险回看/图鉴承接)。来源=UI 重设计原型 v2 落码计划裁决记录(已退役,git 历史可查 §七)。**设计提纲已成文**:[systems/跨局循环/生涯.md](design/gdd/systems/跨局循环/生涯.md) v0.1 范围草案五节成文〔信息架构/承载内容清单/与既有界面关系/分期实装建议/待裁点〕,P0-P5 六裁点已全裁并写入文档〔P0甲 提纲落现行事实源 / P1甲 主菜单一级入口 / P2甲 每局一行摘要+cap 扩容 N+补用时埋点 / P3甲 敌人图鉴优先 / P4甲 局内不放入口+生涯零跳转 / P5甲 settlement_review 复活承接〕。**期一已落地**(2026-10-07 迭代 18 卡④实装批:生涯页六类九项+主菜单入口+终身计数域存档 v6,批末重闸全绿;实机人闸=体验验证清单⑲ 生涯页目检节)。剩余面=期二(历史回看/图鉴)与期三实装+P6 营地最近冒险条带去留(新发现待裁点,随提纲评审一并裁)。**迭代 19 卡②遗留件(2026-10-08 登记)**:settlement_review_overlay.gd 现态考证=未接线遗留件(全仓零引用,M9 结算框改版「明细回看」钮退役后遗留)——处置两途:①随生涯实装批按 P5 甲复活承接(重接线入生涯);②确认不再需要则正式退役删除文件;二选一归生涯实装批/用户裁。Alpha 出口裁决:期二、期三全部排 Beta——Alpha 只保留期一,不在 Alpha 内做生涯新内容。 -**缺口**:还差提纲用户评审收尾与 P6 营地最近冒险条带去留裁决——裁完才能立期二/期三实装卡(期一已交付,期二/三未预占排期)。 +**缺口**:还差提纲用户评审收尾与 P6 营地最近冒险条带去留裁决——裁完才能立期二/期三实装卡(期一已交付,期二/三未预占排期)。本条排 Beta,不阻塞 Alpha;重启时再补 P6 与 N 终值。 **归属**:新界面立项(用户发令后排批);退役落码随 UI 落码批 M8/M9 -**状态**:待文档设计 +**状态**:待文档设计(备选) ### GP 经济 From d5d17ca2d2df8d58ad5c15d2f3c7219cc9151b84 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 07:04:15 +0800 Subject: [PATCH 58/59] =?UTF-8?q?docs(=E5=85=B3=E5=8D=A1=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E5=9B=BE=E5=86=85=E5=AE=B9=E5=B1=82):=20=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=8F=AF=E8=A7=81=E6=80=A7=E5=8D=95=E5=9C=88=E9=9B=BE=EF=BC=8B?= =?UTF-8?q?=E5=B2=94=E8=B7=AF=E5=8F=96=E8=88=8D=E5=8F=8C=E5=B1=82=E7=BA=A6?= =?UTF-8?q?=E6=9D=9F=EF=BC=8B=E6=89=A9=E5=B1=95=E8=8A=82=E7=82=B9=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E4=BD=8D=E2=80=94=E2=80=94=E7=94=9F=E6=88=90=20v1.1/?= =?UTF-8?q?=E5=9C=B0=E5=9B=BE=20v2.1=EF=BC=8C=E5=A4=87=E9=80=89=E6=9D=A1?= =?UTF-8?q?=E7=9B=AE=E7=99=BB=E8=AE=B0=EF=BC=8C=E6=96=87=E6=A1=A3=E5=9F=9F?= =?UTF-8?q?=E9=97=B8=E5=85=A8=E7=BB=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/gdd/systems/冒险循环/关卡节点图生成.md | 21 +++++++++++++------ design/gdd/systems/冒险循环/关卡节点地图.md | 18 +++++++++++++--- 待办清单.md | 17 +++++++++++++-- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/design/gdd/systems/冒险循环/关卡节点图生成.md b/design/gdd/systems/冒险循环/关卡节点图生成.md index b103a984..fc702680 100644 --- a/design/gdd/systems/冒险循环/关卡节点图生成.md +++ b/design/gdd/systems/冒险循环/关卡节点图生成.md @@ -1,7 +1,7 @@ # 关卡节点图生成 > 一句话:一关的节点图从哪来——生成器按参数长出一张合法图 -> 状态:现行为 v1.0 +> 状态:现行为 v1.1 ## 设计目的 @@ -67,17 +67,25 @@ | 分支密度 | 岔口多少、宽度长多快 | | 配比 | 节点类型分布(见下节) | | 入口个数 | 图从几个点进场 | -| 出口个数 | 图通向几个终点(1=单出口;2 及以上=多出口+归属锁定) | +| 出口个数 | 图通向几个终点(1=单出口;2 及以上=多出口+归属锁定;大岔口自第二关起进入参数档,第一关出口恒为 1) | 每关一套参数档(L1/L2/L3),生成器只吃参数档、不认关卡号。生长曲线:层高、宽度、节点总数、路径长度逐关递增且增幅变大;决策点密度逐关递增;第一关即含岔口——第一关也要有选择。单链是分支密度取下限的合法退化形态,不作为三关参数档的取值。 ### 节点类型配比:类型分布怎么掷、内容归谁 -配比是生成旋钮:战斗/奖励/恢复/商店各占多少由参数档定,生成器掷出分布落在图上成为节点类型;配比只管非终点节点,终点恒为 Boss、不进配比。类型构成在图上公开呈现——看得见类型才谈得上提前规划,这是选路成为决策的前提。 +配比是生成旋钮:战斗/奖励/恢复/商店各占多少由参数档定,生成器掷出分布落在图上成为节点类型;配比只管非终点节点,终点恒为 Boss、不进配比。节点类型在可见范围内对玩家公开(可见性规则归关卡节点地图)——看得见的类型才谈得上提前规划。 -摆放约束:每个终点前一位恰一家商店——每名玩家一局必经恰一家店。 +摆放约束(三条): -内容归各 owner:战斗节点打谁=敌人系统按深度带配池;奖励/恢复/商店的兑付语义=关卡节点地图与各 owner 文档。精英、事件这类新类型进不进图、怎么进,归内容层专题;要进就走本文档修订,类型扩展与配比调整一起落。 +| 约束 | 内容 | +|---|---| +| 商店位 | 每个终点前一位恰一家商店——每名玩家一局必经恰一家店 | +| 岔路取舍·下一跳 | 一个岔口分出的各条去路,下一节点类型互不相同——下一跳必在可见范围,是决策的可见锚 | +| 岔路取舍·支路构成 | 一个岔口分出的各条支路,整条支路的节点类型构成互不相同——每条支路至少有一个别的支路没有的类型(例:一路有恢复节点、一路有奖励节点) | + +内容归各 owner:战斗节点打谁=敌人系统按深度带配池;奖励/恢复/商店的兑付语义=关卡节点地图与各 owner 文档。 + +扩展节点类型位:现行四类之外预留扩展位,内容未设计、登记见待办清单「扩展节点类型」条。扩展通道四步=加枚举类型+落兑付实现+调生成配比+走本文档修订。 ## 依赖与输出 @@ -101,7 +109,7 @@ | 岔口去路数 | 2–3 | 每次取舍在 2–3 条里选:少了没选择,多了不过脑 | 已锁 | | 分支密度 | 待定值 | 一局遇到多少次取舍(目标量级=一局十几次,待设计验证) | provisional | | 入口个数 | 1 起 | 多入口给「从哪进场」的第一层选择 | provisional | -| 出口个数 | 1–3 | 多终点让「走哪条=打谁」成立 | 已锁范围 | +| 出口个数 | L1 恒 1;L2/L3 1–3 | 多终点让「走哪条=打谁」成立;大岔口自第二关起 | 已锁范围 | | 配比 | 四类占比合计 1,战斗保底优先 | 攻击性/兑付/恢复的节奏配比 | provisional | | 战斗节点保底数 | ≥ 调参值 | 成长位不挤没战斗——战斗是本作核心量 | provisional | | 商店数 | =出口数 | 每局决战前恰一次补给,成长保底是结构事实 | 已锁 | @@ -114,6 +122,7 @@ | 生长递增 | L1/L2/L3 读数:最长路径步数与节点总数均逐关递增;节点总数增幅 Δ(L2→L3)>Δ(L1→L2) | | 归属锁定 | 多出口图每个终点前一层节点的去路集合恰含一个终点;各分支区域互不连达 | | 必经恰一店 | 任意入口→终点路径经过且恰经过一家店 | +| 岔路取舍 | 任意岔口各去路下一节点类型互不相同;各条支路的节点类型构成互不相同 | | 可复现 | 同种子+同参数档=同一张图 | | 无软回退 | 不存在兜底图路径;参数无解即致命中止 | | 战斗保底 | 任意合法产出的战斗节点数 ≥ 保底数 | diff --git a/design/gdd/systems/冒险循环/关卡节点地图.md b/design/gdd/systems/冒险循环/关卡节点地图.md index f0b41963..f716fc77 100644 --- a/design/gdd/systems/冒险循环/关卡节点地图.md +++ b/design/gdd/systems/冒险循环/关卡节点地图.md @@ -1,7 +1,7 @@ # 关卡节点地图 > 一句话:单关内的节点图选路与推进 -> 状态:现行为 v2.0 +> 状态:现行为 v2.1 ## 设计目的 @@ -50,7 +50,7 @@ 一关内部是一张**有方向的节点图**:节点之间用连线(本文含义:节点之间允许前进的通道)连接,玩家沿连线从一个节点走到下一个节点。结构铁律的规则语义以[关卡节点图生成](关卡节点图生成.md)的产出规格为准,走图视角三句:连线只朝前进方向(没有回头路,整张图无环);每条路径恰好从一个入口出发、恰好到达一个终点;终点恒为 Boss(终点可以有多个,走哪条路决定打谁)。违反任何一条的行集是配置违约,加载期拦截。 -图上只有五种节点,封闭枚举,扩类一律走文档修订: +图上现行五种节点,**可扩展枚举**(扩展通道=加枚举类型+落兑付实现+调生成配比+本文档与[关卡节点图生成](关卡节点图生成.md)同批修订;扩展位见关卡节点图生成配比节): | 节点类型 | 机制承诺 | |---|---| @@ -90,6 +90,18 @@ Boss 兑付(胜利或英雄死亡)触发关卡收束点,此后不再有选路——关卡已定局,后续流程归冒险结构。 +### 选路信息可见性:近处见类型,远处起雾 + +看图选路时玩家知道什么,三条: + +| 层 | 可见什么 | +|---|---| +| 图结构 | 全图可见:节点、连线、入口、终点位置——路线形状永远明牌 | +| 节点类型 | 可见范围(邻近 N 层)内可见;范围外信息迷雾,只见结构、不见类型 | +| 节点内详情 | 图上从不显示——打谁、给什么到兑付才揭晓;内容生成时已定,不是到达随机 | + +终点恒为 Boss,**Boss 标记与终点身份不入雾**——「走哪条=打谁」是提前承诺,承诺必须有信息前提:雾遮的是途中有什么,不遮终局打谁。N 为本系统自有参数(见调参表)。 + ### 节点兑付:把控制流移交给小循环 **人话阶段**:节点兑付就是"走到这个房间里,这个房间的事开始发生"。本文按节点类型触发兑付,然后把属于别家领域的事交还给别家——本文自始至终不生产任何数值。 @@ -157,7 +169,7 @@ Boss 兑付(胜利或英雄死亡)触发关卡收束点,此后不再有选 ## 调参表 -暂无本系统自有的参数——选路与行进无数值可调。图结构合法性是规则不是参数(规则语义见[关卡节点图生成](关卡节点图生成.md)的产出规格),由加载校验强制;图的来源与节点构成归[关卡节点图生成](关卡节点图生成.md),战斗数值归难度曲线与Boss。 +本系统自有参数一项——**信息可见层数 N**(int ≥ 1,provisional,定值批落数据表):节点类型可见距离(层),范围外信息迷雾只见结构。图结构合法性是规则不是参数(规则语义见[关卡节点图生成](关卡节点图生成.md)的产出规格),由加载校验强制;图的来源与节点构成归[关卡节点图生成](关卡节点图生成.md),战斗数值归难度曲线与Boss。 ## 验收标准 diff --git a/待办清单.md b/待办清单.md index 5394e4ed..823d2b47 100644 --- a/待办清单.md +++ b/待办清单.md @@ -102,8 +102,8 @@ **现状**:来源=playnote 用户试玩记录「关卡节点图展示得有问题,希望可以优化一下。可以参考哥布林弹珠的那种方式去移动」。2026-10-13 用户明确定性:**这是当前关卡节点图的重构,不是呈现优化**——理由是**现在的可选节点太少**(用户原话),所以不是换一种画法或移动方式就能解决的事。 关联文档清单: -- 设计定稿 design/gdd/systems/冒险循环/关卡节点图生成.md v1.0(2026-10-21) -- 设计定稿 design/gdd/systems/冒险循环/关卡节点地图.md v2.0(2026-10-21) +- 设计定稿 design/gdd/systems/冒险循环/关卡节点图生成.md v1.1(2026-10-21) +- 设计定稿 design/gdd/systems/冒险循环/关卡节点地图.md v2.1(2026-10-21) **现行实态**(`level.tres` 实查,三关各 5 张模板):**第一关五张模板全是单链排列变体**——7 个节点=战斗 ×4 + 奖励 + 休整 + Boss,战斗深度序单调保难度坡,**变化面只有奖励与休整两位的先后次序**,全链零分叉,玩家在选路上**没有任何选择**;第二/三关是网状图(10 节点,带 `next` 分支,最大层宽 4–5),有分叉,但用户仍判选择量不足。参考方向=Peglin(哥布林弹珠)的节点图移动与选路方式。 @@ -117,6 +117,19 @@ **状态**:文档设计已闭合 +#### 扩展节点类型——危险/精英节点与特殊地形节点(2026-10-21 登记,来源=会话提及,设计面=文档轨) + +**现状**:用户 2026-10-21 会话定方向:Alpha 版只留现行四类(战斗/奖励/恢复/商店),以下两类留到以后再做——①危险/精英节点(怪物与普通战斗不同、奖励肥);②特殊地形节点(效果修饰:地图战斗资源、敌我伤害、金币比例等)。内容未设计。 + +关联文档清单: +- 相关文档 design/gdd/systems/冒险循环/关卡节点图生成.md v1.1(2026-10-21,扩展节点类型位概念) + +**缺口**:两类扩展节点的机制形态与数值未设计(用户明示暂不进 Alpha)。 + +**归属**:[关卡节点图生成](design/gdd/systems/冒险循环/关卡节点图生成.md)(扩展节点类型位+配比) + +**状态**:待文档设计(备选) + #### 天赋树实装批登记欠账余两件——AP 上限 clamp 与三选一刷新软上限(2026-10-12 登记,来源=批次移交,设计面=文档轨) **现状**:迭代 21 天赋树实装批顺带入册欠账三条,2026-10-13 三件终态:① **AP 上限 clamp 缺位(缺陷)**——树「开局姿态」(每关首轮 AP+1)、AP 件、时沙同走 `action_economy.gd:239 _pending_ap_delta` 排队,轮始兑现仅下限钳制(`:254 maxi(0, …)`,无上限);**用户裁暂不设上限**——provisional 天花板亦不投,随未来数值标定窗口连同全部 AP 数值统一标定(M4 数值批已废)。② **三选一刷新软上限(设计问)**——停点内 GP 付费刷新倍率增长(×1.8/次曲线)×停点间基础价随进度递增,全程无软上限;**定性确认=设计问非缺陷,用户裁维持现状**,归未来数值标定窗口处理,不提前单开讨论。③ **Y(_attune_refresh_y)不入断点存档(可利用漏洞)**——已修复注销(2026-10-13 用户令提前单独开修:断点快照扩列 `attune_refresh_y`+续玩 `resume_adventure` 优先读断点〔缺键回退参数面=旧档行为零变化〕+单测两断言;冒烟 938/0+单测 24 套全绿)。①②留待办清单待未来数值标定窗口(M4 数值批已废;2026-10-18 用户裁=不另行归属、未设计未启动)。 From 1a3b87366f2f51bb3c3d1dd350caa80caf25d163 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 21 Oct 2026 07:13:01 +0800 Subject: [PATCH 59/59] =?UTF-8?q?docs(Alpha=E5=87=BA=E5=8F=A3=E8=A1=A5?= =?UTF-8?q?=E5=85=85):=20=E8=90=A5=E5=9C=B0=E4=BA=A4=E4=BA=92=E9=87=8D?= =?UTF-8?q?=E5=81=9A=E4=BA=94=E5=8D=A1=E6=95=B4=E4=BD=93=E5=88=97=E5=85=A5?= =?UTF-8?q?=20Alpha=E2=80=94=E2=80=9408=20v1.12=20=E5=BC=80=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E6=9D=A1=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 用户 2026-10-21 裁:营地表现优化按宽口径处理,五卡(存档制/主菜单三入口/ 选档界面/营地场景图/Esc 浮窗与营地顶栏)整体进 Alpha - 08「三·界面」新增营地交互重做行,状态待做;出口=五卡各自验收通过+营地屏用户目检 - 08「六·Alpha 不含」拆开贴图债:营地柜台随卡④进 Alpha,元进度件终稿留 Beta - 待办清单:营地五卡条目记入 Alpha 依赖;贴图债条目收窄为元进度件 --- design/gdd/08-Alpha版本标准.md | 9 +++++---- 待办清单.md | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/design/gdd/08-Alpha版本标准.md b/design/gdd/08-Alpha版本标准.md index 3bc7d7e8..c9d410f8 100644 --- a/design/gdd/08-Alpha版本标准.md +++ b/design/gdd/08-Alpha版本标准.md @@ -2,7 +2,7 @@ > **一句话定位**:本文定义这个项目的 **Alpha 版本包含哪些东西**——它是里程碑 M3 的完成标准,也是判断"还差什么"的对照表。 > **本文只列条目,不写内容**:每样东西是什么、规则怎么走,一律归各自的权威文档,本文只给指路链接。想知道某样东西的定义,请点链接,不要在本文里找解释。 -> **状态**:**已定稿(v1.11)**——2026-10-13 用户令定稿,此后十一次升版的明细见 git 提交史。Alpha 的内容范围自此冻结:增删条目一律须经用户裁决。 +> **状态**:**已定稿(v1.12)**——2026-10-13 用户令定稿,此后十二次升版的明细见 git 提交史。Alpha 的内容范围自此冻结:增删条目一律须经用户裁决。 > **成文**:2026-10-13。 ## 本文怎么用 @@ -20,7 +20,7 @@ 四个循环下的全部子系统。分界与职责见 [02-系统清单](02-系统清单.md),本文不重复。 -Alpha 内只推进玩法循环本身的内容与表现(棋盘、关卡、战斗);跨局循环等非玩法面不新增内容,新内容排 Beta。 +Alpha 内以玩法循环本身的内容与表现为主(棋盘、关卡、战斗);跨局循环等非玩法面不新增内容,新内容排 Beta。例外=营地交互重做五卡,2026-10-21 用户裁列入 Alpha(见「三 · 界面」表)。 ### 排雷循环 @@ -102,7 +102,8 @@ Alpha 内只推进玩法循环本身的内容与表现(棋盘、关卡、战 |---|---|---| | 主菜单 | —— | 在役 | | 开始覆盖层 | —— | 在役 | -| 营地(天赋树 / 锻造工坊 / 秘宝匣 / 图鉴) | [camp](ux/camp.md) | 在役(锻造柜台占位面板注已解除;柜台贴图占位排 Beta,不碍在役判定) | +| 营地(天赋树 / 锻造工坊 / 秘宝匣 / 图鉴) | [camp](ux/camp.md) | 在役(锻造柜台占位面板注已解除;柜台贴图占位随营地交互重做列入 Alpha,见下行) | +| 营地交互重做(五卡:存档制数据层/主菜单三入口/选档界面/营地场景图/Esc 浮窗与营地顶栏) | [camp](ux/camp.md)+[需求澄清](../research/需求澄清-营地交互重做-2026-10-18.md) | 待做(2026-10-21 用户裁:五卡整体列入 Alpha,含营地表现优化——可点击场景图/顶栏/Esc 浮窗。五卡已写、待编排;卡④营地场景图为最大件,挂三个用户侧前置未销号:美术渠道 A/B、点选反馈设计稿、参照物。出口=五卡各自验收标准通过+营地屏用户目检通过) | | 生涯页 | [生涯](systems/跨局循环/生涯.md) | 在役(期一) | | 关卡地图屏 | [level-map](ux/level-map.md) | 在役 | | 战斗屏 | [battle](ux/battle.md) | 在役 | @@ -195,7 +196,7 @@ Alpha 内只推进玩法循环本身的内容与表现(棋盘、关卡、战 | 第四关 | 排 Beta;全库无设计承载,N>3 走扩展批流程([03-内容规模](03-内容规模.md)) | | 生涯期二(历史冒险回看)与期三(图鉴) | 排 Beta;Alpha 只保留期一([生涯](systems/跨局循环/生涯.md)) | | 素材升档重产 | 排 Beta;原始动机已由八敌逐键定档解决,剩余提灯候选随 Beta 资产批重议([待办清单](../../待办清单.md)) | -| UI 贴图重构(营地与元进度件终稿) | 排 Beta;营地柜台与元进度图标在 Alpha 保留占位,不碍在役判定([美术资产清单](../art/art-assets-checklist.md)) | +| 元进度件贴图终稿 | 排 Beta;元进度图标在 Alpha 保留占位,不碍在役判定([美术资产清单](../art/art-assets-checklist.md))——营地柜台贴图已随营地交互重做列入 Alpha(见「三 · 界面」表) | --- diff --git a/待办清单.md b/待办清单.md index 823d2b47..f1bdb893 100644 --- a/待办清单.md +++ b/待办清单.md @@ -10,9 +10,9 @@ **状态**:待裁决 -#### UI 贴图重构批——营地与元进度件仍是程序化占位(2026-10-13 登记,来源=审计发现,设计面=美术轨) +#### UI 贴图重构批——元进度件仍是程序化占位(2026-10-13 登记,来源=审计发现,设计面=美术轨) -**现状**:营地的柜台场景贴图目前是程序化画出来的临时形态,没有上贴图。这条债原先只写在美术侧的资产清单里([美术资产清单](design/art/art-assets-checklist.md) 第 134 行与第 175 行,原文注明"营地现为程序化占位,状态记录 121⑧ 口径,排期归 UI 贴图重构批"),2026-10-13 由 UI 美化三层诊断转立本清单专条。规格其实已经定了——烛光黄 `#F6C667` 配木色 `#8A5A34`(见 [美术圣经](design/art/art-bible.md) §4.4),素材来源允许走"通用图标改色复用"这条低成本渠道。Alpha 出口裁决:不进 Alpha,排 Beta——营地与元进度件贴图在玩法循环之外,Alpha 保留占位。 +**现状**:营地的柜台场景贴图与元进度图标目前都是程序化画出来的临时形态,没有上贴图。这条债原先只写在美术侧的资产清单里([美术资产清单](design/art/art-assets-checklist.md) 第 134 行与第 175 行,原文注明"营地现为程序化占位,状态记录 121⑧ 口径,排期归 UI 贴图重构批"),2026-10-13 由 UI 美化三层诊断转立本清单专条。规格其实已经定了——烛光黄 `#F6C667` 配木色 `#8A5A34`(见 [美术圣经](design/art/art-bible.md) §4.4),素材来源允许走"通用图标改色复用"这条低成本渠道。2026-10-21 用户裁营地交互重做五卡整体列入 Alpha:营地柜台贴图随之转入卡④营地场景图新建批(新场景取代现四柜台覆盖层),本条只余元进度件贴图终稿,排 Beta。 **缺口**:还差一次「自己画 vs 找 CC0 素材改色」的美术裁决(见 [美术资产清单](design/art/art-assets-checklist.md) §0 的复用渠道闸),裁决后才能定素材工单写卡。 @@ -570,7 +570,7 @@ #### 营地交互重做·五张需求卡片(2026-10-18 登记,来源=会话提及,设计面=文档轨) -**现状**:2026-10-17~18 需求讨论澄清会话产出结论文档,用户令按工作内容维度拆卡、卡片不预占迭代号。五卡已写(顺序=执行顺序):①存档制数据层改造批 ②主菜单三入口化批 ③选档界面新建批 ④营地场景图新建批 ⑤Esc 浮窗与营地顶栏批(各卡估时与内容见卡片自身)。三道复核:grilling 子 Agent 对抗审查(五卡各一)→v1.1;用户裁定「事项按推荐的来」→v1.2;用户两次订正(**卡④留在批内不踢出**;前置归用户自立批,Agent 不代跑不代产——曾越权起草的点选反馈设计稿 v0.1 已撤回删除)→卡④ v2.2。①②③⑤ 零待裁点可编工程波次:②③ 硬耦合同波(「进入存档」钮落点=选档界面),① 是 ③ 前置;⑤ 随 ④ 代码波同行。关联文档: +**现状**:2026-10-17~18 需求讨论澄清会话产出结论文档,用户令按工作内容维度拆卡、卡片不预占迭代号。五卡已写(顺序=执行顺序):①存档制数据层改造批 ②主菜单三入口化批 ③选档界面新建批 ④营地场景图新建批 ⑤Esc 浮窗与营地顶栏批(各卡估时与内容见卡片自身)。三道复核:grilling 子 Agent 对抗审查(五卡各一)→v1.1;用户裁定「事项按推荐的来」→v1.2;用户两次订正(**卡④留在批内不踢出**;前置归用户自立批,Agent 不代跑不代产——曾越权起草的点选反馈设计稿 v0.1 已撤回删除)→卡④ v2.2。①②③⑤ 零待裁点可编工程波次:②③ 硬耦合同波(「进入存档」钮落点=选档界面),① 是 ③ 前置;⑤ 随 ④ 代码波同行。Alpha 出口裁决(2026-10-21 用户裁):五卡整体列入 Alpha——08「三 · 界面」已开条目,Alpha 出口依赖五卡完工与卡④三个用户侧前置销号。关联文档: - 设计澄清定稿:design/research/需求澄清-营地交互重做-2026-10-18.md(v1.0:目标体验原话/目标结构树+纵深稿/10 条交互裁决/验收口径/切批原则/遗留待裁) - 卡①:reports/需求卡片-存档制数据层改造批-2026-10-18.md - 卡②:reports/需求卡片-主菜单三入口化批-2026-10-18.md