diff --git a/CLAUDE.md b/CLAUDE.md index 143b3ace..d1265348 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -18,54 +18,56 @@ 工作目录 = 切片目录本身(含 `project.godot` 的那一层): -- 冒烟(全量 headless 断言):`python tools/run_smoke.py`(包装器三闸:退出码+摘要失败数+SCRIPT ERROR 扫描——脚本错误不计冒烟失败数且静默中断所在函数剩余断言,2026-09-19 状态记录 84 立闸)。底层命令 = `…console.exe --headless --path . --script res://smoke/smoke_all.gd` -- 场景级探针(呈现层回归):`…console.exe --headless --path . res://smoke/ui_probe.tscn`;另有 `ui_tune_probe.tscn`(调试浮窗——2026-10-04 迭代 14.5 起原数值调整板收进 debug_overlay)、`ui_click_probe.tscn`(合成鼠标事件行为探针) -- 调参期批量工具:`--script res://smoke/adventure_monte_carlo.gd`(全冒险期望扫描)· `--script res://smoke/reward_expectation.gd`(奖励获取期望)——单关直入口口径已退役(2026-09-23 用户拍板),通关率/难度类测量一律走全冒险(原 level_monte_carlo/level_debug 已删) -- 数值验证工具:`python tools/balance_verifier.py`(零强化冒险逐关条件通关率+止步节点归因+营地循环爬升战役——采集端 `--script res://smoke/verifier_batch.gd`,报告落 `design/qa/`;元进度换算率标定与曲线调参的自动化评判面,2026-09-22 数值验证工具批;直入口带判定随口径退役暂停,带重锚归曲线调参批) -- 交付前验收 = smoke + 全部场景探针全绿(测试细则见 `design/dev/code-conventions.md`) -- 结构审计闸(熵增闸):`python tools/repo_structure_audit.py`——顶层目录/根文件/图像白名单/退役路径四查,违例 FAIL;新类别 = 同批修订 CLAUDE.md Project Layout + 脚本白名单,commit 留痕(2026-09-27 立闸) +- 冒烟(全量 headless 断言):`python tools/run_smoke.py`。包装器三闸:退出码+摘要失败数+SCRIPT ERROR 扫描——脚本错误不计冒烟失败数,但会静默中断所在函数的剩余断言,读结果必须核对 SCRIPT ERROR 段。底层命令 = `…console.exe --headless --path . --script res://smoke/smoke_all.gd` +- 场景级探针(呈现层回归):`…console.exe --headless --path . res://smoke/ui_probe.tscn`;另有 `ui_tune_probe.tscn`(调试浮窗,数值调整板在 debug_overlay 内)、`ui_click_probe.tscn`(合成鼠标事件行为探针) +- 调参期批量工具:`--script res://smoke/adventure_monte_carlo.gd`(全冒险期望扫描)· `--script res://smoke/reward_expectation.gd`(奖励获取期望)。通关率/难度类测量一律走全冒险,单关直入口口径已退役 +- 数值验证工具:`python tools/balance_verifier.py`(零强化冒险逐关条件通关率+止步节点归因+营地循环爬升战役——采集端 `--script res://smoke/verifier_batch.gd`,报告落 `design/qa/`;元进度换算率标定与曲线调参的自动化评判面)。直入口带判定暂停使用,重锚归曲线调参批 +- 交付前验收 = smoke + 全部场景探针全绿(测试细则见 `design/dev/test-conventions.md`) +- 结构审计闸(熵增闸):`python tools/repo_structure_audit.py`——顶层目录/根文件/图像白名单/退役路径四查,违例 FAIL;新类别 = 同批修订 CLAUDE.md Project Layout + 脚本白名单,commit 留痕 ## Project Layout - `design/gdd/` — 现行设计文档树(根索引 `02-系统清单.md`;文档增删必须同步它;`gdd/ux/` 战斗画面与交互规格) - `design/registry/` — 跨系统事实登记(entities.yaml 术语与已锁数值、architecture.yaml 架构登记) - `design/art/` — 美术**纯文档**:定稿规范 md(圣经/清单/提示词卡)+ `references/` 参考池;评估/调研 md 一律 `design/research/`;**不放任何图片** -- `design/dev/` — 工程规范:code-conventions / doc-conventions / architecture(ADR) / engine-reference -- `design/qa/` — 验证报告 md(balance-verifier/playtest/等价证明;raw 数据归 `sim-data/`)+QA 呈现产物图(目检预览拼图等——2026-09-29 迭代 5 返工批收编图像白名单) +- `design/dev/` — 工程规范:code-conventions / test-conventions / concept-conventions / doc-conventions / architecture(ADR) / engine-reference +- `design/qa/` — 验证报告 md(balance-verifier/playtest/等价证明;raw 数据归 `sim-data/`)+QA 呈现产物图(目检预览拼图等) - `design/research/` — 调研/提案/评估记录/历史验收/执行工单 -- `artwork/` — **在途图像素材唯一工作区**(2026-09-27 用户三层裁定:文档归文档/在途图归一处/终稿归游戏):生图候选批次(每批一目录+每资产一目录+vN 命名)、像素稿、样张渲染、实机截图全在这里;**整目录不入 git——2026-10-02 用户裁:内容永久保留本地、永不提交(md 例外一并取消,.gitignore `artwork/` 强制)**;收口归档 `archive/` +- `artwork/` — **在途图像素材唯一工作区**(三层归位:文档归文档/在途图归一处/终稿归游戏):生图候选批次(每批一目录+每资产一目录+vN 命名)、像素稿、样张渲染、实机截图全在这里;**整目录不入 git——内容永久保留本地、永不提交(md 例外一并取消,.gitignore `artwork/` 强制)**;收口归档 `archive/` - `game/assets/art/` — 已验收终稿(入包被游戏加载) -- `game/` — 游戏工程本体:代码三件套+`smoke/` 冒烟套件+`tests/` 单元/集成测试(2026-09-27 根 tests/ 并入) -- `sim-data/` — 机器读数据产物:模拟试玩 CSV/JSON、verifier raw 基线、日志样例输出。**数据件不入 git(2026-10-03 用户立规:.gitignore 强制)——语义=MC 缓存层:最新一份 MC 锚+读数常驻留盘供分析直读,无数值调整禁重跑(细则见「测试执行两入口铁规」MC 触发细则);`iteration_log.md` 模拟批日志同目录留盘不入库。入库例外三件(2026-10-03 二裁)=`README.md`+`analyze.py`+`growth_model.py`(分析工具本体随 git)** +- `game/` — 游戏工程本体:代码三件套+`smoke/` 冒烟套件+`tests/` 单元/集成测试 +- `sim-data/` — 机器读数据产物:模拟试玩 CSV/JSON、verifier raw 基线、日志样例输出。**数据件不入 git(.gitignore 强制)——语义=MC 缓存层:最新一份 MC 锚+读数常驻留盘供分析直读,无数值调整禁重跑(细则见硬性红线「测试执行两入口铁规」MC 触发细则);`iteration_log.md` 模拟批日志同目录留盘不入库。入库例外三件=`README.md`+`analyze.py`+`growth_model.py`(分析工具本体随 git)** - `tools/` — python 工具脚本本体(验证/审计/像素化/仪表盘/日志分析) -- 根目录运行文件:`active.md`(会话状态唯一状态源——快照+未决面+当前迭代工作记录;状态文件非历史档案,历史归 git,退役规则见 `design/dev/doc-conventions.md` §10)、`roadmap.md`(里程碑)、`stage.txt`/`review-mode.txt`(运行开关) +- 根目录运行文件:`active.md`(会话状态唯一状态源——快照+未决面+当前迭代工作记录;状态文件非历史档案,历史归 git,退役规则见 `design/dev/doc-conventions.md` 第 10 节)、`roadmap.md`(里程碑)、`stage.txt`/`review-mode.txt`(运行开关) - `archive/` — 收口归档 zip(gitignored) ## 规范导航(动手前先查表) | 时机 | 权威文档 | |---|---| -| **写代码 / 改代码前** | `design/dev/code-conventions.md`——结构 / 契约 / 测试 / 语言 / 数值 / 流程六类硬纪律 + 反面案例对照表 | -| **写文档 / 改文档前** | `design/dev/doc-conventions.md`——可读性第一、白话写作、概念封装、引用纪律、文档骨架、文档生命周期(吸收即死) | +| **写代码 / 改代码前** | `design/dev/code-conventions.md`——结构 / 契约 / 语言 / 数值 / 流程五类硬纪律(含真实反面案例) | +| **写测试 / 改测试前** | `design/dev/test-conventions.md`——探针标配 / 回归断言 / 提交前全量验证 / 验收清单落码规范 | +| **写文档 / 改文档前** | `design/dev/doc-conventions.md`——可读性第一、白话写作、载体分工、用语纪律、结构与骨架、会话记录与文档生命周期 | +| **设计文档的概念切分与互链** | `design/dev/concept-conventions.md`——概念封装建模 / 跨文档引用纪律 / 归档与事实源 | | 查系统设计 / 增删文档 | `design/gdd/02-系统清单.md`——根索引 + 中文规范名↔英文代号对照表 | | 架构与决策记录 | `design/dev/architecture/architecture.md` + 同目录 `adr-*.md` | | 引擎版本与参考 | `design/dev/engine-reference/godot/`(版本表已在上方 @ 引入) | | 术语、已锁数值 | `design/registry/entities.yaml`——仅 owner 文档可修订,冲突须显式提出 | -| 会话进度记录 | 根目录 `active.md`(状态文件,2026-10-09 立宪:只记现在,每行当下为真)——快照节(≤10 条)+未决面+当前迭代状态记录;收口先改快照再记账,并删除已完结旧条目;历史归 git、待裁归 06、教训归记忆库;条目用完整白话句子写清结论,能看懂比短重要(2026-10-04 用户立规),详情归权威文档 | +| 会话进度记录 | 根目录 `active.md`(状态文件:只记现在,每行当下为真)——快照节(≤10 条)+未决面+当前迭代状态记录;收口先改快照再记账,并删除已完结旧条目;历史归 git、待裁归 06、教训归记忆库;条目用完整白话句子写清结论,能看懂比短重要,详情归权威文档 | | 工程路线图 | 根目录 `roadmap.md`——里程碑时间线与下一步顺序(批级视图;实时状态看快照节) | -## 分支纪律(worktree 铁律,2026-09-19 用户立规) +## 分支纪律(worktree 铁律) 主工作区(本目录,`master` 检出)只作**合并落点与共享状态载体**,一切开发/设计改动不得直接发生在主工作区: 1. **开工**:每个任务批次先建独立 worktree 分支再动手:`git worktree add ../g-plan2-<任务名> -b <任务分支>`。所有代码/文档/数值改动与验证跑测都在 worktree 内进行(注意:未跟踪文件不会出现在新 worktree,需手工搬运) -2. **收尾**:迭代 loop 批次在验证全绿(冒烟 + 场景探针;冒烟挂迭代开发完成后的出口/入库闸)后,在主工作区 `git merge --no-ff <任务分支>` 落回 master,然后 `git worktree remove` + 删分支;合并前先看 active.md 尾部状态记录,避免与并行会话撞号/漏捎带;收口时按 doc-conventions §10 退役规则删除已完结旧条目(判据=已入库+结论进快照+无未决项指向)。非 loop 批次收口跑闸与否按「测试执行两入口铁规」(见硬性红线):默认不跑,用户点名或当场问 +2. **收尾**:迭代 loop 批次在验证全绿(冒烟 + 场景探针;冒烟挂迭代开发完成后的出口/入库闸)后,在主工作区 `git merge --no-ff <任务分支>` 落回 master,然后 `git worktree remove` + 删分支;合并前先看 active.md 尾部状态记录,避免与并行会话撞号/漏捎带;收口时按 doc-conventions 第 10 节退役规则删除已完结旧条目(判据=已入库+结论进快照+无未决项指向)。非 loop 批次收口跑闸与否按「测试执行两入口铁规」(见硬性红线):默认不跑,用户点名或当场问 3. **豁免面(仅这两处允许主工作区直改)**:根目录 `active.md`(会话收口)与 `.zcode/`(钩子配置)——其余一律走 worktree;主工作区 `git commit` 会被钩子直接拦截 4. 本铁律由 PreToolUse 钩子 `.zcode/hooks/worktree-guard.sh` 强制兜底;钩子只约束 agent 侧,用户本人手工改动不受限 -## 三段开发流程(2026-10-10 用户立规) +## 三段开发流程 -一切要做的东西按三段走:**设计 → 写需求卡片 → 实现**。段与段之间不自动流转,每段转进由用户发令;本节只立出入口与铁律,段内细则见规范导航各文档。背景:2026-10-10 武器锻造取证确认「迭代」曾被当作一切批次的容器(设计提案混进迭代通道),导致「迭代完成了但游戏里没有」的口径错位——本节为此立规。 +一切要做的东西按三段走:**设计 → 写需求卡片 → 实现**。段与段之间不自动流转,每段转进由用户发令;本节只立出入口与铁律,段内细则见规范导航各文档。 **第一段·设计**——产出 GDD 文档或 art-bible。 - 触发:用户提起,或从 `design/gdd/06-待办清单.md` 取出讨论。 @@ -82,9 +84,9 @@ **第三段·实现**——产出代码与配置文件,可运行的游戏。 - 触发:需求卡片永不单独施工,统一由用户指定迭代号触发(=U0 开工令);执行按 /iter 技能与下方批次工作流标准清单。 - **设计权威文档(GDD/art-bible 等承载设计决定的文档)在实现批内一律不更新**——文档与用户想法等同对等,任何更新必须经用户同意;实现批只出迭代实现报告(见下方第 12 条文档同步闸)。 -- 收口人闸:实机目检清单+代拍板追认单登记交用户即完成批内义务;真人检测不阻塞收口、不阻塞后续迭代开工,用户自行安排时间验收(2026-10-12 用户立规,替代旧「用户验完才算真完」口径)。 +- 收口人闸:实机目检清单+代拍板追认单登记交用户即完成批内义务;真人检测不阻塞收口、不阻塞后续迭代开工,用户自行安排时间验收。 -## 批次工作流标准清单(2026-10-06 用户确认固化) +## 批次工作流标准清单 每个批次按以下链路执行——本清单主要承载第三段(实现段)与一切被批准批次的执行纪律,三段的出入口与转进规则见上节。本清单是总索引,各步细则散见上文各节与 `design/dev/` 子文档;与任一细则冲突时以细则为准,发现清单本身过时须同批修订。 @@ -99,37 +101,38 @@ 6. **涉数值改动先采改前读数**——批次要改游戏数值的,改码前先采「改前」模拟读数(与改后同随机种子配对比较),并写明对拍口径;无数值改动禁跑模拟(触发细则见硬性红线) **实施** -7. **新功能必配新测试**——按需求卡片卡片写码,新增玩法/机制必须配套新增测试套件进 `tests/run_all`;没有对应测试的变更不许合并 +7. **新功能必配新测试**——按需求卡片写码,新增玩法/机制必须配套新增测试套件进 `tests/run_all`;没有对应测试的变更不许合并 8. **验收改动先行声明**——逻辑变更对应的验收变化(模拟基线换代、探针用例增改、旧断言改判)在需求卡片里预先写明,不事后补 **收口** 9. **批末四闸全绿才合并**——冒烟 + 单元测试 + 场景探针 + 改前改后读数对拍,四项全绿方可在主工作区合并 10. **合并后主区全量复跑**——合并本身可能引入冲突或环境差异,落回 master 后再跑一遍全套验证 -11. **会话收口落记**——`active.md` 快照与状态记录更新(含删除已完结旧条目,退役规则见 `design/dev/doc-conventions.md` §10);跨会话有效的教训写入记忆库 -12. **文档同步闸 v2(2026-10-10 用户改立,替代 2026-10-09 版)**——文档更新时间点分两层:**机械面文档**(roadmap 行换代、registry、active.md 记账、README/工具注)合并/入库前随批更新完毕方算收口(原口径不变);**设计权威文档**(GDD/art-bible 等承载用户设计决定的文档)实现批内一律不更新——文档与用户想法等同,更新必须经用户同意:实现批收口产出**迭代实现报告**(`design/qa/iter-实现报告-<日期>.md`,一个迭代一份,含各卡状态+代拍板追认单+**GDD 反哺点节**——实现与设计的差异/缺口逐条列明),反哺点收口时同步登记 `design/gdd/06-待办清单.md`,用户逐点裁决后另批落文(可随批捎带,窗口长短由用户控制)。反哺点未落文期间,相关 GDD 节按 06 登记视为待反哺状态——读该节做新设计/写新卡前先查 06,勿把旧文当现行事实。需求卡片仍必列「关联文档同步面」,同步义务按两层标注(机械面=随批更新;设计面=报告反哺) -13. **实机目检归用户,只登记不阻塞**——真人检测项由 agent 登记进迭代实现报告目检总清单与 07-体验验证清单,登记完毕批内义务即完成;自动化闸全绿即可合并收口,用户自行安排时间验收,结论按 07 清单回流路径回流;禁止把「等用户目检」当作停工理由或任务完成的必要前置(2026-10-12 用户立规,替代原「用户验完才算验收通过」口径) -14. **中间产物吸收即死**——结论先迁入权威文档(GDD/待办清单/路线图),中间文件即删且永不提交(细则见硬性红线) +11. **会话收口落记**——`active.md` 快照与状态记录更新(含删除已完结旧条目,退役规则见 `design/dev/doc-conventions.md` 第 10 节);跨会话有效的教训写入记忆库 +12. **文档同步闸**——文档更新时间点分两层:**机械面文档**(roadmap 行换代、registry、active.md 记账、README/工具注)合并/入库前随批更新完毕方算收口;**设计权威文档**(GDD/art-bible 等承载用户设计决定的文档)实现批内一律不更新——文档与用户想法等同,更新必须经用户同意:实现批收口产出**迭代实现报告**(`design/qa/iter-实现报告-<日期>.md`,一个迭代一份,含各卡状态+代拍板追认单+**GDD 反哺点节**——实现与设计的差异/缺口逐条列明),反哺点收口时同步登记 `design/gdd/06-待办清单.md`,用户逐点裁决后另批落文(可随批捎带,窗口长短由用户控制)。反哺点未落文期间,相关 GDD 节按 06 登记视为待反哺状态——读该节做新设计/写新卡前先查 06,勿把旧文当现行事实。需求卡片仍必列「关联文档同步面」,同步义务按两层标注(机械面=随批更新;设计面=报告反哺) +13. **实机目检归用户,只登记不阻塞**——真人检测项由 agent 登记进迭代实现报告目检总清单与 07-体验验证清单,登记完毕批内义务即完成;自动化闸全绿即可合并收口,用户自行安排时间验收,结论按 07 清单回流路径回流;禁止把「等用户目检」当作停工理由或任务完成的必要前置 +14. **中间产物吸收即死**——结论先迁入权威文档(GDD/待办清单/路线图),中间文件即删且永不提交(细则见硬性红线「中间产物吸收即死」与 `design/dev/doc-conventions.md` 第 11 节) ## 硬性红线(勿违反) -- **worktree 铁律**:主工作区禁止直接改动与提交(细则见上节;并行会话各占 worktree 互不踩踏) -- **测试执行两入口铁规(2026-10-02 用户立规)**:测试类执行——冒烟测试、单元测试(tests/run_all)、模拟验证(MC/verifier/调参批量工具)、场景探针等一切跑游戏的验证调用——只有两个触发入口:①**迭代 loop 开发**(冒烟挂迭代开发完成后的出口/入库闸,loop 内过程性验证属开发工作本身);②**用户主动点名**。除此之外(问答/调研/文档/审查/零散小改等短小会话)一律零测试,不得擅自调用任何测试;确需测试支撑结论时先请示,以静态阅读/推理作答并注明未跑测。**MC/模拟验证触发细则(2026-10-02 用户确认,2026-10-03 补落文——出处:迭代 9 出口批 81000 锚误跑质询)**:MC/verifier 仅在**数值验证场景**触发(改数值前后取证);normal 档为主、perfect 按需;**无数值改动的会话禁跑 MC**——结构位移类「存档锚」须先向用户请示定性再跑;需求卡片预设步骤的前提消失时(如「带值裁定后重锚」实际未投值)停问勿照字面执行。**分级周期口径(2026-09-26 用户裁定,2026-10-03 自 06-待办清单收编;重闸定义随迭代 19 卡①需求卡片 Q1 裁决扩容 2026-10-08)**:轻闸(run_smoke 全量+ui_input_probe;触碰 presentation 加跑 ui_click_probe+ui_layout_probe)可随变更执行;**重闸自此批末=轻闸+probe_gate --click+probe_gate --full(ui_probe/ui_tune_probe/t17_defer_probe/fx_probe 四探针)+render_gate(窗口化渲染闸:shot_probe 七屏样张 A-D 断言+fx_shot/board_shot 取证+棋盘 golden 逐像素)+run_all 单元全套+doc 三闸(gdd_lint/doc_link_audit/doc_term_audit)+熵增闸(repo_structure_audit)**,属**周期执行**——统一在批次收口或固定周检跑,不进每次变更;真人实机目检仍归用户不进自动闸(07⑮ 目检半不销号);MC 大扫描仍按上方 MC 触发细则(无数值改动零跑) -- **闸机轮次纪律(2026-10-14 用户立规,起因=迭代 27 T0/T1 实证全套闸白跑 4-5 轮)**:①【孤立验证先行】任何新代码/新工具/新测试断言,进入全套闸轮换之前,必须先走通最小可运行路径的 standalone 验证(30 秒级:新断言=单独驱动函数直跑;新工具=最小参数全路径试车含产出落盘;新探针=单 .tscn 直跑),禁以全套闸首跑充当新码首验;②【调试期最窄确认】闸机出红→修复→确认只跑出红的最小单元(单探针/单套件/单函数),禁修一处跑全套——全套闸每个里程碑步(波/T 段)出口最多一次,红灯补跑只跑红件;例外:修的若为全部探针/套件共用的共享件(如冒烟包装器、闸机脚本本身),全套即最小充分单元,注记说明即可;③【长批试车】≥2 分钟的跑批(逐位对拍冻结/MC 批/批量模拟)发起前,先用最小参数把工具完整路径(含解析/落盘/写锚全链)跑通一遍再放长批;④【开工坑册扫描】每波/T 段开工前,按要触碰的面扫一遍在册坑(worktree 缓存三件套、--script 模式无 autoload、守卫文本匹配等),5 分钟预防性动作,禁运行期撞坑补课 -- **MC 采集档位细则(2026-10-03 用户四档立规,承接 MC 触发细则)**:MC 局数按用途四档硬闸(表见 `sim-data/README.md`「MC 采集档位表」):**一档·调研**=总量 >40(100+ 为常用锚量级;60/档=结构回归、100=95% CI ±9.8pp、170=±7.5pp=15pp 带半宽、400 满档=±4.9pp 贴边裁决;normal 独立满档 ~8 分钟同属一档)**只能由用户发起**——需求卡片/计划书/agent 均无权发起,非用户发起一律不构成一档授权;**二档·数值修改验证**=总量 ≤40、每档 ≤20(仅 ≥~40pp 结构位移可判,同种子配对下 ~30pp);**三档·小调**=总量 ≤20、每档 ≤10(只测不判);**四档·微量**=总量 ≤5(sanity 门,零统计判读)。四档仅承接 MC 触发细则的数值验证场景,两入口铁规不变;超档=停机呈报,禁在二/三/四档下带值结论(窗口不足如实挂起)。改前/改后锚同 seed0 配对、改前锚留盘禁补跑;对拍断言零新跑(复验用锚内子集 ≤20);读数缺陷(零 gameplay/RNG 触碰)禁整套重跑、走事件流重构补算;≥60 局采集先 N=5 pilot 校验字段;二/三/四档会话累计 ≤20 分钟;零数值改动=零 MC -- **中间产物吸收即死(2026-10-01 立规)**:中间文档(批需求卡片/机检报告/调研审计报告/模拟读数/迭代计划书/目检清单)寿命=迭代寿命——结论先吸收进权威文档、未决项先迁 `design/gdd/06-待办清单.md` 或 roadmap,然后文件即删,且永不提交 git;活文档=唯一事实源,git=变更记录。细则见 `design/dev/doc-conventions.md` 第 11 节 -- **用语红线(2026-10-04 用户立规,黑话审计后落文)**:面向用户的一切输出——文档、状态记录(active.md)、报告、清单、对话——禁止自造黑话与代号式命名;判据 = 业内读者没读过项目历史也能一遍看懂,需要作者解释才能懂的词必须展开成完整白话句(三种固定形态、本仓反例全表与正确写法见 `design/dev/doc-conventions.md` 第 4 节) -- **呈报六问铁规(2026-10-07 用户立规)**:向用户呈报一切事物——bug、需求、概念设计、提案——一律按六问结构顺序展开,确认后才动手实现:①**What 现状与差异**——现在是什么样(引用文件、行为等事实)+ 要做什么/改什么;②**Why 期望与动机**——目标态是什么样、为什么值得改,含「不做的代价」;③**How 怎么改**——修改路径,有备选案全部列出不私藏;④**Where 影响面**——改动波及哪些系统、文件、流程、既有裁决;⑤**怎么算改对了**——可判定的验收标准,不写模糊话;⑥**不确定的地方**——没把握、需要用户裁决的点,单列收尾不埋正文。**Who/When 不进呈报正文**——谁来执行、什么时候做由用户决定,由 roadmap 与需求卡片承接,呈报里最多一句话带过。**适用范围(2026-10-08 用户补立)**——六问结构只用于**首次描述需求、bug 缺陷或相关方案**的呈报;同一方案的后续对答(追问、讨论、细化、执行汇报)不再套用六问结构,除非用户显式要求 - -- **真人检测不阻塞(2026-10-12 用户立规)**:一切需要真人检测/实机目检/人工验收的事项一律「只登记、不等待」——登记进 07-体验验证清单(或当批实现报告目检总清单)即完成 agent 侧义务;自动化闸全绿即可合并收口,后续迭代照常开工,验收时间由用户自行安排。禁止把等真人检测当作任务阻塞点、停工理由或收口必要条件,也禁止因往期遗留真人检测项而拦截新迭代开工 -- **文件头 = `##` 文档注释 ≤8 行白名单制(2026-10-15 用户立规,两轮)**:代码文件(.gd 等)文件头只许 `##` 文档注释、总行数 ≤8、内容限五类白名单(①一行职责摘要 ②用途/验证问题 ③GDD 锚行 ④硬使用约束每条一行 ⑤指路行);黑名单 = 日期、变更叙事(「XX批/T几/迭代N 做了什么」、迁移/改名/退役经过)、与 code-conventions/ADR/架构文档重复的段落、场景结构/生命周期等代码机制描述。写法权威 = Google Python Style Guide §3.8 + PEP 257(GDScript 官方风格指南对文件头零条款,不自造标准);变更叙事唯一归宿 = commit message 与迭代实现报告;规范与架构只指路不复制——"Never describe the code"。机器闸 = `tools/audit_file_headers.py`(static_scan S10),存量头注清偿批在册待发令 +- **worktree 铁律**:主工作区禁止直接改动与提交(细则见「分支纪律」节;并行会话各占 worktree 互不踩踏) +- **测试执行两入口铁规**:测试类执行——冒烟测试、单元测试(tests/run_all)、模拟验证(MC/verifier/调参批量工具)、场景探针等一切跑游戏的验证调用——只有两个触发入口:①**迭代 loop 开发**(冒烟挂迭代开发完成后的出口/入库闸,loop 内过程性验证属开发工作本身);②**用户主动点名**。除此之外(问答/调研/文档/审查/零散小改等短小会话)一律零测试,不得擅自调用任何测试;确需测试支撑结论时先请示,以静态阅读/推理作答并注明未跑测 + - **MC/verifier 触发细则**:仅在**数值验证场景**触发(改数值前后取证);normal 档为主、perfect 按需;**无数值改动的会话禁跑 MC**——结构位移类「存档锚」须先向用户请示定性再跑;需求卡片预设步骤的前提消失时(如「带值裁定后重锚」实际未投值)停问勿照字面执行 + - **分级周期口径**:轻闸(run_smoke 全量+ui_input_probe;触碰 presentation 加跑 ui_click_probe+ui_layout_probe)可随变更执行;**重闸=轻闸+probe_gate --click+probe_gate --full(ui_probe/ui_tune_probe/t17_defer_probe/fx_probe 四探针)+render_gate(窗口化渲染闸:shot_probe 七屏样张 A-D 断言+fx_shot/board_shot 取证+棋盘 golden 逐像素)+run_all 单元全套+doc 三闸(gdd_lint/doc_link_audit/doc_term_audit)+熵增闸(repo_structure_audit)**,属**周期执行**——统一在批次收口或固定周检跑,不进每次变更;真人实机目检仍归用户不进自动闸;MC 大扫描按上方 MC 触发细则(无数值改动零跑) +- **闸机轮次纪律**:①【孤立验证先行】任何新代码/新工具/新测试断言,进入全套闸轮换之前,必须先走通最小可运行路径的 standalone 验证(30 秒级:新断言=单独驱动函数直跑;新工具=最小参数全路径试车含产出落盘;新探针=单 .tscn 直跑),禁以全套闸首跑充当新码首验;②【调试期最窄确认】闸机出红→修复→确认只跑出红的最小单元(单探针/单套件/单函数),禁修一处跑全套——全套闸每个里程碑步(波/T 段)出口最多一次,红灯补跑只跑红件;例外:修的若为全部探针/套件共用的共享件(如冒烟包装器、闸机脚本本身),全套即最小充分单元,注记说明即可;③【长批试车】≥2 分钟的跑批(逐位对拍冻结/MC 批/批量模拟)发起前,先用最小参数把工具完整路径(含解析/落盘/写锚全链)跑通一遍再放长批;④【开工坑册扫描】每波/T 段开工前,按要触碰的面扫一遍在册坑(worktree 缓存三件套、--script 模式无 autoload、守卫文本匹配等),5 分钟预防性动作,禁运行期撞坑补课 +- **MC 采集档位细则**:MC 局数按用途四档硬闸(全表见 `sim-data/README.md`「MC 采集档位表」):**一档·调研**=总量 >40,**只能由用户发起**——需求卡片/计划书/agent 均无权发起,非用户发起一律不构成一档授权;**二档·数值修改验证**=总量 ≤40、每档 ≤20;**三档·小调**=总量 ≤20、每档 ≤10(只测不判);**四档·微量**=总量 ≤5(sanity 门,零统计判读)。四档仅承接 MC 触发细则的数值验证场景,两入口铁规不变;超档=停机呈报,禁在二/三/四档下带值结论(窗口不足如实挂起)。改前/改后锚同 seed0 配对、改前锚留盘禁补跑;对拍断言零新跑(复验用锚内子集 ≤20);读数缺陷(零 gameplay/RNG 触碰)禁整套重跑、走事件流重构补算;≥60 局采集先 N=5 pilot 校验字段;二/三/四档会话累计 ≤20 分钟;零数值改动=零 MC +- **中间产物吸收即死**:中间文档(批需求卡片/机检报告/调研审计报告/模拟读数/迭代计划书/目检清单)寿命=迭代寿命——结论先吸收进权威文档、未决项先迁 `design/gdd/06-待办清单.md` 或 roadmap,然后文件即删,且永不提交 git;活文档=唯一事实源,git=变更记录。细则见 `design/dev/doc-conventions.md` 第 11 节 +- **用语红线**:面向用户的一切输出——文档、状态记录(active.md)、报告、清单、对话——禁止自造黑话与代号式命名;判据 = 业内读者没读过项目历史也能一遍看懂,需要作者解释才能懂的词必须展开成完整白话句(三种固定形态、反例全表与正确写法见 `design/dev/doc-conventions.md` 第 4 节) +- **呈报六问铁规**:向用户呈报一切事物——bug、需求、概念设计、提案——一律按六问结构顺序展开,确认后才动手实现:①**What 现状与差异**——现在是什么样(引用文件、行为等事实)+ 要做什么/改什么;②**Why 期望与动机**——目标态是什么样、为什么值得改,含「不做的代价」;③**How 怎么改**——修改路径,有备选案全部列出不私藏;④**Where 影响面**——改动波及哪些系统、文件、流程、既有裁决;⑤**怎么算改对了**——可判定的验收标准,不写模糊话;⑥**不确定的地方**——没把握、需要用户裁决的点,单列收尾不埋正文。**Who/When 不进呈报正文**——谁来执行、什么时候做由用户决定,由 roadmap 与需求卡片承接,呈报里最多一句话带过。**适用范围**——六问结构只用于**首次描述需求、bug 缺陷或相关方案**的呈报;同一方案的后续对答(追问、讨论、细化、执行汇报)不再套用六问结构,除非用户显式要求 +- **真人检测不阻塞**:一切需要真人检测/实机目检/人工验收的事项一律「只登记、不等待」——登记进 07-体验验证清单(或当批实现报告目检总清单)即完成 agent 侧义务;自动化闸全绿即可合并收口,后续迭代照常开工,验收时间由用户自行安排。禁止把等真人检测当作任务阻塞点、停工理由或收口必要条件,也禁止因往期遗留真人检测项而拦截新迭代开工 +- **文件头 = `##` 文档注释 ≤8 行白名单制**:代码文件文件头只许 `##` 文档注释、总行数 ≤8、内容限五类白名单;日期与变更叙事入黑名单;写法权威 = Google Python Style Guide §3.8 + PEP 257(不自造标准);机器闸 = `tools/audit_file_headers.py`(static_scan S10)。白名单/黑名单全表见 `design/dev/code-conventions.md` §1.4.1 - **数值单一事实源**:玩法数值只存 `data/tables/`(.tres),经 `ConfigDB` autoload 类型化单点读取;禁止数值字面量与自建 `load()` 表路径 -- **RNG 单点**:禁止 `randomize()` / 自建 RandomNumberGenerator——随机只经 `RngService` 统一流(单盐单计数器+用途标签+全事件日志,ADR-0007 裁丙 2026-09-27) +- **RNG 单点**:禁止 `randomize()` / 自建 RandomNumberGenerator——随机只经 `RngService` 统一流(单盐单计数器+用途标签+全事件日志,ADR-0007 裁丙) - **Core 层零 UI 依赖**:完整战斗必须可 `--headless --script` 跑通 - **fail-fast**:数据校验错误一律致命中止,无软回退 - **spec-AC 一致性**:规约与验收标准不得在同一输入上给出不同答案(所有 GDD 同尺度) - **评审隔离**:`/design-review` 必须在独立会话跑(与 `/design-system` 隔离) -## 像素结构件工作纪律(2026-09-26,高墙批转角三返工复盘用户令落档) +## 像素结构件工作纪律 1. **先抄后造**:画任何像素结构件前,先从参考素材裁同类结构放大逐像素描述,再实现同款;禁止凭印象/第一性原理发明像素结构(圣经 §8.5 参考核验的执行口径)。 2. **验收口径写成像素级视觉判据**:开工前把合格标准写成"X 与 Y 同列收尾/无悬空/无突出"式句子;自检放大最差交界处逐行核像素,不只看整板观感。 diff --git a/design/dev/code-conventions.md b/design/dev/code-conventions.md index d98d9f04..b24be849 100644 --- a/design/dev/code-conventions.md +++ b/design/dev/code-conventions.md @@ -1,9 +1,7 @@ # 代码规范(Dungeon Sweeper) -> 生效:2026-09-11 · 来源:用户在垂直切片评审中逐一指出的真实陋习与缺陷,全部成文。 -> 每条规则附本项目真实反面案例(标注缺陷编号/日期)——规则不是抽象美德,是踩过的坑。 -> 约束范围:`game/`(原 prototypes/ 垂直切片,2026-09-24 转正)代码同尺度;与 CLAUDE.md「硬性红线」节既有硬约束 -> (数值表单点 / RNG 封闭流 / Core 零 UI / fail-fast / spec-AC 一致性)并行生效,冲突以用户裁决为准。 +> 约束范围:`game/` 代码同尺度;与 CLAUDE.md「硬性红线」节硬约束(数值表单点 / RNG 封闭流 / Core 零 UI / fail-fast / spec-AC 一致性)并行生效,冲突以用户裁决为准。 +> 分工:本文管结构 / 契约 / 语言 / 数值 / 流程五类;测试的编写与验收纪律见 `design/dev/test-conventions.md`。 **写任何代码前必须通读本文件。** @@ -15,16 +13,14 @@ 一个类只承载一个职责。场景主脚本(main)= **组合根**:模式流转、信号接线、核心写调用的唯一出口; 渲染、文案拼装、状态装配一律拆分为独立视图/装配器类。单文件超过 ~400 行即触发审视。 -> **反面案例(2026-09-11,用户:"一个工程师看了想吐")**:main.gd 随功能追加长到 ~1100 行——棋盘渲染、 -> HUD、结算日志格式化、四种模态覆盖层、调整板、蒙特卡洛模拟器、关卡流程全部糊在一个类里。 -> 已拆分为 9 个单一职责单元(views/ + hud_presenter),main 降到 433 行组合根。 +> 反例:main.gd 曾长到 ~1100 行——棋盘渲染、HUD、结算日志格式化、四种模态覆盖层、调整板、 +> 模拟器、关卡流程全部内联;后拆分为 9 个单一职责单元(views/ + hud_presenter),main 回到 ~430 行组合根。 ### 1.2 一切功能以类封装,禁止裸函数堆 设计稿与实现同尺度:功能 = 类(状态 + 行为 + 信号),类是封装的最小交付单位。 工具性纯函数只允许挂在明确的宿主类下(静态装配器/工厂),不允许无主散落。 -> **反面案例(2026-09-11,用户:"我看你都是函数的方式……没有对象封装吧")**:供给控制器的伪代码 -> 以裸函数呈现被否;正式实现按"B4 私有组合件 RewardSupplyController"封装。 +> 反例:供给控制器曾以裸函数伪代码呈现被否;正式实现按私有组合件 RewardSupplyController 封装。 ### 1.3 依赖单向,核心写调用收口 依赖方向唯一:`views →(信号)→ 组合根 →(写调用)→ core`。 @@ -37,10 +33,10 @@ `# 实现 GDD:design/gdd/systems/<循环>/<系统文档>.md(系统 ID Xn)`;系统 ID 只作为文档与 registry 的追溯锚。 豁免:D2 schema 类与 autoload(本就领域命名);文档/夹具登记名(如 b4_golden)属文档层。 -> **反面案例(2026-09-11,用户:"是没有代码规范吗")**:ID 前缀是跟随 GDD 文档名的事实约定, -> 从未成文;同目录 `config_db`/`rng_service` 无前缀与 A/B/C 系列并存——两套命名即规范缺失的铁证。 +> 反例:ID 前缀是跟随 GDD 文档名的事实约定,从未成文;`config_db`/`rng_service` 无前缀与 A/B/C 系列 +> 并存——两套命名并行即规范缺失。 -### 1.4.1 文件头 = `##` 文档注释,≤8 行,白名单制(2026-10-15 第二轮立规) +### 1.4.1 文件头 = `##` 文档注释,≤8 行,白名单制 文件头注释只用 `##` 文档注释(Godot 官方载体,进编辑器 F1 帮助),总行数 ≤8 行(不含空行, 从文件首个非空行到首个非注释代码行)。写法权威 = Google Python Style Guide §3.8 + PEP 257 @@ -62,10 +58,9 @@ 机器闸:`tools/audit_file_headers.py`(static_scan S10:行数上限 + 黑名单机械可判子集; 信号契约成文位置见 §2.1)。存量头注按白名单清偿后挂入收口闸序列;此间新增/改动的文件头必须即合规。 -> **反面案例(main.gd,两轮,2026-10-15)**:第一轮头注累积 42 行——11+ 笔提交各自追加「本批做了什么」, -> 全部闸静默放行;清偿删叙事后仍剩 31 行——约 2/3 是对 code-conventions §1.3 与 ADR-0001 的整段复制、 -> 场景结构/生命周期机制描述(对规约与代码零新信息),且第 4 行残留带日期批次叙事。第二轮立规后 -> 全仓头注按白名单重写,机制事实归 design/dev/architecture。 +> 反例:main.gd 头注曾累积 42 行——历次提交各自追加「本批做了什么」而全部闸静默放行;删掉叙事后 +> 仍剩 31 行,约 2/3 是对 code-conventions §1.3 与 ADR-0001 的整段复制、场景结构/生命周期机制描述 +> (对规约与代码零新信息)。全仓头注按白名单重写,机制事实归 design/dev/architecture。 ### 1.5 禁止事实约定 任何"大家默认这么做"的惯例必须成文进本文件(或 CLAUDE.md)才算存在。 @@ -80,67 +75,33 @@ (参照 A2 三事件面先例);计入 §1.4.1 的 8 行上限,塞不下时迁契约文档并在文件头留指路行。 状态机的每次迁移路径都必须发出对应事件——**缺一条路径的事件 = 消费方永久等待 = 软锁**。 -> **反面案例(playtest 缺陷②)**:A2 旗动作花完末点 AP 后相位翻 Waiting 但不发 round_end, -> B1 结算点依赖该事件 → 整局软锁。v1 冒烟没抓到是因为自动玩家不用旗——路径覆盖不全的代价。 +> 反例:旗动作花完末点 AP 后相位翻 Waiting 但不发 round_end,结算点依赖该事件 → 整局软锁; +> 自动玩家不用旗,冒烟路径覆盖不全没抓住。 ### 2.2 跨层标识符语义单一且成文 位置(index)/ 句柄(handle)/ 键(key)是三种不同的东西。跨类传递标识符时, 传递方的语义必须与接收方契约逐字一致,禁止凭"当前恰好相等"传值。 -> **反面案例(playtest 缺陷④)**:窗口选择契约 = 窗口条目位置,UI 却传库存数组句柄—— -> 未消耗时二者巧合相等;消耗一件后错位 → 选中件不消耗、邻件被误耗。 +> 反例:窗口选择契约 = 窗口条目位置,UI 却传库存数组句柄——未消耗时二者巧合相等; +> 消耗一件后错位 → 选中件不消耗、邻件被误耗。 ### 2.3 模态覆盖层层级规则 覆盖层遮挡关系由场景树加入顺序决定。打开任何模态覆盖层时,必须显式隐藏会遮挡它的全屏层; 新增覆盖层必须登记其在 z 序中的位置,并提供"打开可见性"的场景断言。 -> **反面案例(playtest 缺陷⑤)**:数值调整板已实现,但打开时被不透明的开始覆盖层完全遮住 -> = "点击无反应"。功能存在 ≠ 功能可达。 +> 反例:数值调整板已实现,但打开时被不透明的开始覆盖层完全遮住 = "点击无反应"。功能存在 ≠ 功能可达。 ### 2.4 状态字段语义显式 跨战斗/跨场景携带或恢复的状态字段,其语义来源必须显式(表值 / 明确入参),禁止用入参隐式定义。 -> **反面案例**:B2 spawn 把 hero 的 max_hp 设为入参 hero_hp——跨战斗携带 HP 时上限被压扁, +> 反例:spawn 把 hero 的 max_hp 设为入参 hero_hp——跨战斗携带 HP 时上限被压扁, > 恢复点/治疗包的满血守卫全部失效。 --- -## 3. 测试纪律——"存在"必须证明"可达且正确" +## 3. 测试纪律 -### 3.1 场景级探针标配 -每新增一个可交互 UI 区域(视图/覆盖层/面板),必须配套场景级 headless 探针: -真实实例化场景 → 驱动真实输入路径 → 断言可见性与状态。**只有 core 层 AC 通过不算有测试** -(GDScript 编译不查字典字段与时序,呈现层错误只在运行时暴露)。 - -### 3.2 覆盖层/面板必测"打开后可见" -凡模态覆盖层,探针必须断言:打开后自身 visible 且遮挡物已隐藏(缺陷⑤回归断言)。 - -### 3.3 缺陷修复必须沉淀回归断言 -每个缺陷修复必须在探针或冒烟中留下能抓住该缺陷的断言(旗动作耗尽 AP → 必须进入第 2 轮; -选用道具 → 库存态必须变 Used)。没有回归断言的修复视为未完成。 - -### 3.4 提交前全量验证 -交付前必须全绿:`smoke_all.gd` + 全部场景探针(ui_probe / ui_click_probe / ui_tune_probe)。 -行为探针使用随机化玩家行为(旗/停手/刷新/无效点击)——自动玩家不做的动作就是测试盲区。 - -### 3.5 测试函数怎么写——验收清单条目的落码规范(2026-10-11 用户立规) - -需求卡片 §7「逐需求点验收清单」每一条都要落成可执行的验证;本节定统一写法,卡里定每批的具体内容(测什么/注入哪里)。写卡期查不出执行载体的条目=不可测,当场呈报,禁拖到实现期。 - -1. **执行载体五选一,逐条声明**:单元测试(`tests/run_all`)/冒烟断言(`smoke_all.gd` 对应场景段)/场景探针(`smoke/` 下 `*_probe`)/MC 同种子对拍/人工核对(仅限无法自动化的纪律类需求点,如命名锁定、数值占位)。行为类条目以自动化载体为主。 -2. **粒度与对应关系**:每条清单条目至少一个自动断言;多条条目可合用一个测试函数。断言失败消息末尾带编号尾缀〔卡短名 Vn〕(如〔秘宝批 V3〕)——断言与卡片清单可互相 grep 查找。 -3. **断言词汇按验证对象五选一**: - - | 词汇 | 适用场景 | - |---|---| - | 逐位相等 | 同种子下确定性公式与结算的精确对拍 | - | 区间/差值带 | 概率与平衡读数(MC 同种子配对比较,出带即红) | - | 快照比对 | 存档域结构、配置表行结构 | - | 重放 | 同种子断点回放、改前改后配对 | - | 状态/计数器断言 | 条件解锁、限次、充能——置数据→走路径→断计数值 | - -4. **调试注入两层(测试方式两分法的落码面)**:自动化测试=测试代码直调核心层写口构造状态(直改数据表行/计数器/存档域,不经 UI、不走正常资源积累流程——冒烟现役做法);人工体验=DebugOverlay/DS_DEBUG 调试面,服务用户目检。清单条目的「怎么测」必须写到数据面粒度:改哪张表哪行、置哪个计数、调哪个核心写口。 -5. **换代批旧验证约束同生死**:删除旧数据行/旧实现代码的批次,必须同批摘除只验证旧实现的断言与护栏校验,由新断言替代——旧件断言残留=冒烟假绿来源;合并后冒烟全绿且全仓无旧件残留引用为证。 +已独立成文:`design/dev/test-conventions.md`(探针标配 / 回归断言 / 提交前全量验证 / 验收清单落码规范)。 --- @@ -165,14 +126,14 @@ ("可选类 3.32"不加"每板",会被读成每格期望 >1)。 ### 5.2 调参先测量,改后复测 -改任何玩法数值前,先用扫描工具产出基线(通关率/难度类读数走 `balance_verifier.py` 冒险段——单关直入口口径已退役,机制类读数走 `reward_expectation.gd` 等); -改完必须复测回填数据。禁止拍脑袋调参。 +改任何玩法数值前,先用扫描工具产出基线(通关率/难度类读数走 `balance_verifier.py` 冒险段, +机制类读数走 `reward_expectation.gd` 等);改完必须复测回填数据。禁止拍脑袋调参。 ### 5.3 数值设计必须跨尺度推演 在单一尺度校准的数值,必须推演其在更大尺度的复合结果(每战合理 × 关内囤积 = 关卡灾难)。 -> **反面案例(2026-09-11)**:可选类 25% 格子配比在单战斗尺度校准(击杀需求 18/54), -> ×"库存关内延续"× 5 张板复合后 = 每关 24.8 件、刀总伤 180 > Boss 130 HP——预警⑥在关卡尺度坐实。 +> 反例:可选类 25% 格子配比在单战斗尺度校准(击杀需求 18/54),×"库存关内延续"× 5 张板复合后 +> = 每关 24.8 件、刀总伤 180 > Boss 130 HP——单尺度合理的参数在关卡尺度坐实灾难。 ### 5.4 用户拍板的实现零发挥 拍板范围外的细节一律不自行补全——以"待办问题"清单列出等裁决。 @@ -182,29 +143,6 @@ ## 6. 流程纪律 -1. **大改动三段走**:设计稿/伪代码 → 用户审阅 → 实现 → 修改记录(README + session-state)。实现不得先于审阅。 -2. **实现批收尾双登记**:切片 README 修改记录 + 根目录 `active.md` 条目(会话状态唯一状态源——2026-10-09 定性,路径自 production/session-state/ 迁根目录),缺一不可。 -3. **规范变更必须成文进本文件**——发现未成文约定、或用户裁决产生新规则,当场补条文。 -4. **呈现层缺陷的教训回写 D1 GDD 设计输入**(信号载荷 schema / 场景级测试 / 时点状态可见性)。 - ---- - -## 附:缺陷-规范对照表(本项目真实案例,2026-09-11) - -| 缺陷 | 现象 | 根因 | 对应规则 | -|---|---|---|---| -| ① UI 抖动/"第3轮"消失 | 悬停文案换行推挤侧栏,末行被挤出视口 | 动态内容参与布局回流 | 1.1 拆分 + 视图定长槽(HUDView) | -| ② Boss 战 AP 用完不结算(软锁) | 插旗耗尽末点 AP 后整局冻结 | 旗动作路径缺轮末事件 | 2.1 事件发射完整性 | -| ④ 道具使用后不消失 | 选用件留存、邻件被误耗 | 窗口位置 vs 库存句柄错位 | 2.2 标识符语义单一 | -| ⑤ 调整板点击无反应 | 面板已实现但被开始层遮挡 | 模态打开未隐藏遮挡物 | 2.3 层级规则 + 3.2 | -| 上帝对象 | main.gd ~1100 行 | 职责无边界持续堆积 | 1.1–1.3 | -| ID 前缀命名 | a1_/b1_ 与领域命名并存 | 事实约定未成文 | 1.4–1.5 | -| 可选类每关 24.8 件 | 速杀退化、囤刀秒 Boss | 单尺度校准未做跨尺度推演 | 5.3 | - -## 版本历史 - -| 版本 | 日期 | 说明 | -|---|---|---| -| v1 | 2026-09-11 | 首版成文(垂直切片评审用户逐一指出,全部附真实反面案例) | -| v2 | 2026-10-09 | 文档正确性审查批·独立复核(worktree docaudit-2026-10-09):§6 流程纪律第 2 条「production/session-state/active.md」过期路径改「根目录 active.md」(会话状态唯一状态源,2026-10-09 用户定性为状态文件并迁根目录);本表系本批补建 | -| v3 | 2026-10-11 | 新增 §3.5「测试函数怎么写——验收清单条目的落码规范」(2026-10-11 用户立规,需求卡片逻辑验收方法论批):执行载体五选一逐条声明/断言消息带〔卡短名 Vn〕编号尾缀/断言词汇五选一表/调试注入两层/换代批旧验证约束同生死 | +1. **大改动三段走**:设计稿/伪代码 → 用户审阅 → 实现;实现不得先于审阅。修改记录落切片 README。 +2. **实现批收尾双登记**:切片 README 修改记录 + 根目录 `active.md` 条目(会话状态唯一状态源),缺一不可。 +3. **呈现层缺陷的教训回写 D1 GDD 设计输入**(信号载荷 schema / 场景级测试 / 时点状态可见性)。 diff --git a/design/dev/concept-conventions.md b/design/dev/concept-conventions.md new file mode 100644 index 00000000..ceb1f756 --- /dev/null +++ b/design/dev/concept-conventions.md @@ -0,0 +1,54 @@ +# 概念与引用规范(Dungeon Sweeper) + +> 约束范围:设计文档的概念建模与跨文档引用。写作层(句子、结构、骨架)归 `design/dev/doc-conventions.md`;本文管概念怎么切、文档怎么互链。 +> 概念对象登记 `design/registry/entities.yaml`(owner 与 referenced_by 由此机械维护);文档里概念怎么切,registry 就怎么登记,代码里的对象划分与之同构。 + +**写设计文档前必须通读本文。** + +--- + +## 1. 概念封装纪律(概念对象化建模) + +动笔之前先做概念建模:像写代码划分对象那样,把设计切成分界清晰的概念——每个概念有自己的规范名、自己的属性、自己的规则,概念之间靠显式关系(包含、挂载、引用)连接,而不是把所有内容揉进一个概念里。概念没有边界,删除修改就得全仓翻找。 + +| 规则 | 内容 | +|---|---| +| 概念即对象 | 核心概念各自独立成体,有规范名、有属性、有规则边界;下笔前先能用一句"它是谁、它管什么"说清,说不清就是还没想完 | +| 属性归属唯一 | 每个属性只归一个概念——离开 A 就没有意义的属性写在 A 名下,禁止上提给容器、也不下压给成员 | +| 包含关系显式写 | 容器与成员的关系明文写出谁是容器、谁是成员、一对几(例:棋盘包含多个格);禁止让读者从散文里反推结构 | +| 概念状态用枚举 | 概念的类型与状态写成封闭枚举并列全成员(例:格的类型 = 安全格 / 危险格,格的状态 = 未开 / 已开);禁止用散文形容词零散罗列状态 | +| 附加物独立成对象 | 挂在概念上的附加内容若自己有一组属性或规则要写(例:格上的奖励/惩罚 = 格面资源),就是独立对象——父概念只保留挂载位(如"有无资源资格"),禁止把附加物摊平成父概念的一堆属性字段 | +| 关系不吸内容 | 概念间关系只写"有没有关系、是什么关系";对方的属性与规则留在对方名下——与第 2 节"引用不转述"同源 | +| 落位五要素 | 概念的权威文档必须写全五要素:**定义**(它是什么)/ **作用对象与范围**(作用在谁、什么范围内有效)/ **生命周期**(何时出现、何时变化、何时消失、怎么重置)/ **关联**(与谁衔接、边界归谁、哪些指路别处)/ **状态**(已定稿/待实施/已退役)。缺任何一项都是半成品概念,如同对象缺了构造函数 | + +**切分正例**(现行排雷循环即按此切分):棋盘是地图级对象,包含多个格;格是成员对象,危险格/安全格是它的枚举属性;格上可能挂的奖励或惩罚(格面资源)是独立对象,本体与规则归地图战斗资源与战斗结算,格只保留"有无资源资格"一个挂载位。反面基准:把奖励的类型、数值、极性全摊开写成格子的属性字段——奖励规则一改,棋盘文档就得跟着改,这便是没封装。 + +**无权威文档,不下定义**:一个概念还没有权威文档时,任何其他文档都不得替它下定义——只能引用概念名,并在 `design/gdd/06-待办清单.md` 登记「待落位」;谁先立权威文档,谁拿走全部定义权。(反例:某概念长期无权威文档,art-bible 复述、06 登记、需求卡片摘要三处各自给出口径,范围限定词在层层复述中丢失,最终放大成「全板常显」的错误事实。) + +**与引用纪律的关系**:第 1 节管单个概念的边界与归属(概念级封装),第 2 节管概念之间、文档之间的引用(跨文档解耦)——先有封装,第 2 节的单点定义、反向边与删除 SOP 才有干净的作用对象。 + +## 2. 引用纪律(跨文档高内聚低耦合) + +目标:修改或删除一个概念时,只改它的 owner 文档;引用方最多删掉一个链接。反例模式:同一概念多名并存、机制被织进多份文档的规则正文——删除时全仓几十处文字修改与大量事后一致性复查。 + +| 规则 | 内容 | +|---|---| +| 单点定义 | 每个概念只在 owner 文档里定义一次,registry 术语条目登记其规范名 | +| 规范名唯一 | 正文只准用规范名,禁止别名散开——否则删除时 grep 搜不全 | +| 引用不转述 | 跨文档引用 = 规范名 + 链接,禁止复述对方的规则细节、公式、数值与口径;确需携带口径时,作用对象/范围/生命周期必须随句写全或显式指路——禁止只复述形容词,「常显」「恒亮」这类词不带范围就是半句话;若发现自己需要一条规则,那是自己的概念,先立权威文档再定义 | +| 引用落到对外承诺 | 跨文档链接只锚到对方文档明示的对外内容(事件、接口、规则条目),不锚其内部细节 | +| 依赖逐条列出 | 系统文档的「依赖与输出」节逐条列出本系统依赖的他人概念(规范名 + 链接)——这份清单就是删除概念时的影响面清单 | +| 引用必登记反向边 | 引用他系统概念时,在被引方的 registry 条目 `referenced_by` 里登记——影响面靠它机械列出,不靠全仓搜 | +| 链接断了也好读 | 引用处的句子在链接失效后仍通顺完整(写"变异规则见《地形变异》",不把半截语义挂在链接里) | +| 待办单点登记 | 全项目待办事项单点登记于 `design/gdd/06-待办清单.md`:系统文档的「待办」节只留指路存根,不得自建条目表;新增待办条目直接登记清单,裁决后改「状态」列留痕、不删条目 | + +**引用格式**:一律 Markdown 相对链接,指向文件、必要时带节锚点(例:`[地形变异 · 变异类型](systems/排雷循环/地形变异.md#变异类型)`)——机械可查,死链可被工具检出。 + +**删除概念 SOP**:① 查 registry 该条目的 `referenced_by`,得到影响面清单 → ② owner 文档删除概念 → ③ 纯引用方删链接即完事;机制被织入对方规则的,按清单逐处修订 → ④ 收尾跑一遍死链检查,全绿即干净。 + +**诚实边界**:机制耦合无法靠删链接消灭——别人的规则真的因你的概念而改变时,改内容不可避免。引用纪律保证的是:这类修改有一份现成清单(反向边 + 依赖节),不用事后全仓搜索。 + +## 3. 归档与事实源 + +- 旧文档里的概念写进现行文档时,必须翻译成现行术语与现行决策口径(例:已退役机制不得作为现行机制引用)。 +- registry 中 owner 仍指向旧 GDD 路径的条目,在对应新系统文档定稿后逐条改指新路径。 diff --git a/design/dev/doc-conventions.md b/design/dev/doc-conventions.md index fbeaadbd..ea838ab3 100644 --- a/design/dev/doc-conventions.md +++ b/design/dev/doc-conventions.md @@ -1,8 +1,7 @@ # 文档写作规范(写文档前必读) > **地位**:本文是本项目文档写作的规范权威,与 `design/dev/code-conventions.md`(代码规范)对等——写代码前必读代码规范,写文档前必读本文。CLAUDE.md 只保留导航指针,细则以本文为准。 -> **适用范围**:`design/` 下一切现行文档(顶层文档、`systems/` 系统文档、`design/ux/`、`design/art/`、`design/research/`)、根目录 `active.md` 会话记录与 `roadmap.md`。 -> **成文**:2026-09-14。整合来源:用语纪律(2026-09-09 评审确立)· 文档形态纪律(2026-09-13 评审确立)· 两件套与树形文档体系纪律(2026-09-14 用户拍板)· 新骨架过渡口径(2026-09-14 用户拍板)· 可读性纪律(2026-09-14 用户提出)· 引用纪律(2026-09-14 用户提出)· 概念封装纪律(2026-09-15 用户提出)。 +> **适用范围**:`design/` 下一切现行文档(顶层文档、`systems/` 系统文档、`gdd/ux/`、`design/art/`、`design/research/`)、根目录 `active.md` 会话记录与 `roadmap.md`;概念建模与跨文档引用见 `design/dev/concept-conventions.md`。 ## 0. 总纲 @@ -18,7 +17,7 @@ 答不出来,就重写这一节,而不是给看不懂的地方补注释。 -**与旧体系门禁的关系**:旧体系的 lean 格式六条硬规则已随 2026-09-14 归档停用,仅用于解读 `design/archive/` 里的旧文档(解读时注意其表格占比口径为 30%,2026-09-14 由 60% 放宽)。`tools/gdd_lint.py` 工具同批停用后已恢复为现行文档机检三闸之一(gdd_lint / doc_link_audit / doc_term_audit——分级周期口径见 CLAUDE.md,对现行文档生效);可读性仍是第一内容质量门,lint 是格式机检面,两者并行。旧模板文件留档 `.claude/docs/templates/` 备查。 +**与旧体系门禁的关系**:旧体系的 lean 格式六条硬规则已停用,仅用于解读 `design/archive/` 里的旧文档(解读时注意其表格占比口径为 30%)。`tools/gdd_lint.py` 现为现行文档机检三闸之一(gdd_lint / doc_link_audit / doc_term_audit——分级周期口径见 CLAUDE.md,对现行文档生效);可读性仍是第一内容质量门,lint 是格式机检面,两者并行。旧模板文件留档 `.claude/docs/templates/` 备查。 ## 2. 白话写作规则 @@ -49,21 +48,21 @@ ## 4. 用语纪律(见名知意 · 所见即所得 · 禁自造黑话) -**正面总则(2026-10-10 用户立规):见名知意,所见即所得。** 见名知意——用到的每个名字(概念名、术语、文档与目录名)本身就说清它指什么,读者看到名字、不用等解释就知道大概;起不出这样的名字,多半是概念还没想清,先想清再落笔。所见即所得——读者读到的字面意思就是规则的完整意思,不需要追问作者、翻查项目历史或脑补隐含前提才能还原真实含义;有隐含前提就写进句子,有言外之意就写成正文。这两句管的是把话说明白,不是要求把所有信息都塞进本文——该指路的地方仍按第 8 节指路。本节其余禁令说哪些写法不行,这两句说行的是什么。 +**正面总则:见名知意,所见即所得。** 见名知意——用到的每个名字(概念名、术语、文档与目录名)本身就说清它指什么,读者看到名字、不用等解释就知道大概;起不出这样的名字,多半是概念还没想清,先想清再落笔。所见即所得——读者读到的字面意思就是规则的完整意思,不需要追问作者、翻查项目历史或脑补隐含前提才能还原真实含义;有隐含前提就写进句子,有言外之意就写成正文。这两句管的是把话说明白,不是要求把所有信息都塞进本文——该指路的地方仍按第 8 节指路。本节其余禁令说哪些写法不行,这两句说行的是什么。 -文档、评审输出、日志与一切沟通中**禁止自造黑话**——比喻性生造词、只有作者自己懂的缩略语(历史反例:"非雾腿""双闸")。 +文档、评审输出、日志与一切沟通中**禁止自造黑话**——比喻性生造词、只有作者自己懂的缩略语。 - 只能使用:(a)人人可懂的直白语言,或(b)游戏行业通用术语(如 flood fill、战争迷雾、连锁展开、结算、增益/减伤)。 - 需要指代新概念时,用直白的描述性短语(正例:"实测可推理率"——限定语与规范名绑定)。 - 确需给新概念命名时:首次出现处必须附一句白话定义,并登记 `design/registry` 术语条目——不得让读者猜测比喻含义。 - 唯一例外:玩家在游戏里也会看到的专属名词(道具名、界面用语,如"显影尘""探巢摆钟")。文档内部的机制概念不得造词。 -**自造词的三种固定形态(2026-10-04 黑话审计后补成,全部禁止)**:审计发现本仓自造词几乎都长成下面三种样子,写的时候照着规避,读的时候见到即展开改写: +**自造词的三种固定形态(全部禁止)**——写的时候照着规避,读的时候见到即展开改写: -| 形态 | 反例(本仓真实案例) | 正确写法 | +| 形态 | 反例 | 正确写法 | |---|---|---| -| 给工作包起代号 | "样张批""八型批""资产升档重产批" | 叙述名 = 日期 + 做什么,如"2026-10-01 按新分辨率规格重做素材" | -| 给机制、检查、基线、区域造名词 | "熵增闸""形象锚""判读口径""暗淡记忆态""变异纹带" | 用行业通用词;确实要长期复用的概念走上面的登记通道(正常名字 + 首现白话定义 + registry 登记) | +| 给工作包起代号 | "样张批""八型批""资产升档重产批" | 叙述名 = 日期 + 做什么,如"按新分辨率规格重做素材" | +| 给机制、检查、基线、区域造名词 | "形象锚""判读口径""暗淡记忆态""变异纹带" | 用行业通用词;确实要长期复用的概念走上面的登记通道(正常名字 + 首现白话定义 + registry 登记) | | 给流程步骤造动词 | "收口""落籍""在飞""随批""对拍""销账""正主""台账" | 用日常动词:完成 / 合并进 master / 执行中 / 顺带 / 与基线数据逐项比对 / 注销 / 定义所属的那份文档 / 状态记录 | **通行检验标准**:读者是业内人士,但没读过本项目的历史。一个词如果需要作者另外解释才能懂,这个词就不合格,包含它的句子必须重写成完整的白话句——换一个新名词不算改,展开才算改。 @@ -77,9 +76,16 @@ | 树形文档体系 | 全部设计文档构成一棵树;文档增删必须同步根索引 `design/gdd/02-系统清单.md` | | 一页纸节点 | 一节、一条规则的内容控制在一页纸内(约 ≤80 行);装不下就拆节,禁止铺开 | | 一系统一文档 | 每个子系统一份设计文档,不建 analysis 推演件;两三句能说清的"为什么"直接写进设计目的或规则正文 | -| 正文只写现行规则 | 禁止删除线、"(作废)"、"(日期+拍板)"式注记;修订只进文末「版本历史」表;义务台账、拍板记录等审计信息入 `design/registry` 或附录,不入正文 | +| 正文只写现行规则 | 禁止删除线、"(作废)"、"(日期+拍板)"式注记;义务台账、拍板记录等审计信息入 `design/registry` 或附录,不入正文 | | 后置 ≠ 删除 | P1/P2 后置的内容逐条列出;复活后置项 = 修订文档,禁止静默加回 | -| 数值纪律 | 正文定规则、取值域、单位;平衡值进 `data/tables/`,provisional 必须标注;已锁数值事实源 = `data/tables/` 与 `design/registry/entities.yaml`。**强制收口条款(2026-09-17 数值压缩批后补成)**:① **双写失同步禁止**——任何数值变更(压缩 / 换装 / 投值 / 区间平移 / 增减行)必须同时同步所有引用该数值的 GDD 表格正文、registry `entities.yaml` 的 `mvp_content` / `value_status`、相关待办清单现状——三类之一未更新即视为该变更**未完成**(先例:2026-09-17 整体数值压缩批只动了 `.tres` 与切片代码,未同步 `地图战斗资源.md` / `增益状态.md` 正文表格、`entities.yaml` mvp_content、`06-待办清单.md` 的 `heal 负向直伤` 条目,造成文档滞后);② **调参表锁数后删现行值列**——数值已锁定的调参表必须删除「现行值」列(敌人系统 v0.6 先例),仅保留 schema 模板与取值域,指路存根指向 `data/tables/.tres` 与 `registry/entities.yaml` 对应条目;③ **覆盖范围** = 奖励 / 状态 / 敌人 / 技能 / 充能 / 护甲等级 / 区间掷点 / 难度曲线 / D_ref 等所有数值字段;④ **维护通道** = 走「设计批 → 同步批」两段式——数值表改完不等于修订完成,须同步收口后方可记入版本历史;⑤ **压缩/换装批** = 一律走「`.tres` 落批 + 切片 smoke 跑通 + GDD 表格指路化 + registry mvp_content 指路化 + 待办清单现状刷新」五步全收才记版本号,缺步则版本号不增 | + +**数值纪律**:正文定规则、取值域、单位;平衡值进 `data/tables/`,provisional 必须标注;已锁数值事实源 = `data/tables/` 与 `design/registry/entities.yaml`。强制收口条款: + +1. **双写失同步禁止**——任何数值变更(压缩 / 换装 / 投值 / 区间平移 / 增减行)必须同时同步所有引用该数值的 GDD 表格正文、registry `entities.yaml` 的 `mvp_content` / `value_status`、相关待办清单现状——三类之一未更新即视为该变更**未完成**(反例:数值压缩批只动了 `.tres` 与切片代码,三类文档全部滞后)。 +2. **调参表锁数后删现行值列**——数值已锁定的调参表必须删除「现行值」列,仅保留 schema 模板与取值域,指路存根指向 `data/tables/.tres` 与 `registry/entities.yaml` 对应条目。 +3. **覆盖范围** = 奖励 / 状态 / 敌人 / 技能 / 充能 / 护甲等级 / 区间掷点 / 难度曲线 / D_ref 等所有数值字段。 +4. **维护通道** = 走「设计批 → 同步批」两段式——数值表改完不等于修订完成,须同步收口后方可记入版本历史。 +5. **压缩/换装批** = 一律走「`.tres` 落批 + 切片 smoke 跑通 + GDD 表格指路化 + registry mvp_content 指路化 + 待办清单现状刷新」五步全收才记版本号,缺步则版本号不增。 ## 6. 文档类型与骨架 @@ -104,70 +110,24 @@ | 系统范围 | 负责/不负责两张表;表前一段白话说明边界 | | 在核心循环中的位置 | 处于哪一段、上下游是谁(字符画一行 + 两句白话) | | 核心规则 | 领域章节 ×2–6,每节一页纸 | -| 依赖与输出 | 上游/下游/对外事件与接口(表格;引用纪律见第 8 节) | +| 依赖与输出 | 上游/下游/对外事件与接口(表格;引用纪律见 `design/dev/concept-conventions.md`) | | P0 最小闭环 / P1·P2 后置 | MVP 最小集合与后置清单 | | 调参表 | 参数名/取值域/现行值,provisional 标注 | | 验收标准 | 可验证的判据 | -| 待办(可选) | 指路存根:条目单点登记 `06-待办清单.md`(见第 8 节「待办单点登记」),本节不再逐条登记 | +| 待办(可选) | 指路存根:条目单点登记 `06-待办清单.md`,本节不再逐条登记 | | 版本历史 | 表格 | **命名**:中文、见名知意(如"游戏概念""棋盘生成");禁止 a1_/b1_ 编号前缀;不留纯空目录。正文中指代子系统一律用中文规范名;英文代号(供代码标识符与工具链)对照表见 `design/gdd/02-系统清单.md`,旧代号(a1–d6)仅限解读归档时使用,不得写进现行文档。 -## 7. 概念封装纪律(概念对象化建模) - -动笔之前先做概念建模:像写代码划分对象那样,把设计切成分界清晰的概念——每个概念有自己的规范名、自己的属性、自己的规则,概念之间靠显式关系(包含、挂载、引用)连接,而不是把所有内容揉进一个概念里。揉团的代价雾格事故已经付过一次(见第 8 节反例对照):概念没有边界,删除修改就得全仓翻找。 - -| 规则 | 内容 | -|---|---| -| 概念即对象 | 核心概念各自独立成体,有规范名、有属性、有规则边界;下笔前先能用一句"它是谁、它管什么"说清,说不清就是还没想完 | -| 属性归属唯一 | 每个属性只归一个概念——离开 A 就没有意义的属性写在 A 名下,禁止上提给容器、也不下压给成员 | -| 包含关系显式写 | 容器与成员的关系明文写出谁是容器、谁是成员、一对几(例:棋盘包含多个格);禁止让读者从散文里反推结构 | -| 概念状态用枚举 | 概念的类型与状态写成封闭枚举并列全成员(例:格的类型 = 安全格 / 危险格,格的状态 = 未开 / 已开);禁止用散文形容词零散罗列状态 | -| 附加物独立成对象 | 挂在概念上的附加内容若自己有一组属性或规则要写(例:格上的奖励/惩罚 = 格面资源),就是独立对象——父概念只保留挂载位(如"有无资源资格"),禁止把附加物摊平成父概念的一堆属性字段 | -| 关系不吸内容 | 概念间关系只写"有没有关系、是什么关系";对方的属性与规则留在对方名下——与第 8 节"引用不转述"同源 | -| 落位五要素 | 概念的权威文档必须写全五要素:**定义**(它是什么)/ **作用对象与范围**(作用在谁、什么范围内有效)/ **生命周期**(何时出现、何时变化、何时消失、怎么重置)/ **关联**(与谁衔接、边界归谁、哪些指路别处)/ **状态**(已定稿/待实施/已退役)。缺任何一项都是半成品概念,如同对象缺了构造函数(2026-09-30 微光口径事故后补成) | - -**切分正例**(现行排雷循环即按此切分):棋盘是地图级对象,包含多个格;格是成员对象,危险格/安全格是它的枚举属性;格上可能挂的奖励或惩罚(格面资源)是独立对象,本体与规则归地图战斗资源与战斗结算,格只保留"有无资源资格"一个挂载位。反面基准:把奖励的类型、数值、极性全摊开写成格子的属性字段——奖励规则一改,棋盘文档就得跟着改,这便是没封装。 - -**无权威文档,不下定义**:一个概念还没有权威文档时,任何其他文档都不得替它下定义——只能引用概念名,并在 06-待办清单登记「待落位」;谁先立权威文档,谁拿走全部定义权。(2026-09-30 微光事故:类型微光长期无权威文档,art-bible 复述、06 登记、需求卡片摘要三处各自给出口径,范围限定词在层层复述中丢失,最终放大成「全板常显」的错误事实。) - -**落盘载体**:概念对象登记 `design/registry/entities.yaml`(owner 与 referenced_by 由此机械维护);文档里概念怎么切,registry 就怎么登记,代码里的对象划分与之同构。 - -**与引用纪律的关系**:本节管单个概念的边界与归属(概念级封装),第 8 节管概念之间、文档之间的引用(跨文档解耦)——先有封装,第 8 节的单点定义、反向边与删除 SOP 才有干净的作用对象。 - -## 8. 引用纪律(跨文档高内聚低耦合) - -目标:修改或删除一个概念时,只改它的 owner 文档;引用方最多删掉一个链接。反例对照 = 2026-09-14 雾格删除事故——雾格/迷雾/fog 三名并存、雾机制被织进多份文档的规则正文,导致全仓几十处文字修改与大量事后一致性复查。 - -| 规则 | 内容 | -|---|---| -| 单点定义 | 每个概念只在 owner 文档里定义一次,registry 术语条目登记其规范名 | -| 规范名唯一 | 正文只准用规范名,禁止别名散开——否则删除时 grep 搜不全 | -| 引用不转述 | 跨文档引用 = 规范名 + 链接,禁止复述对方的规则细节、公式、数值与口径;确需携带口径时,作用对象/范围/生命周期必须随句写全或显式指路——禁止只复述形容词,「常显」「恒亮」这类词不带范围就是半句话(2026-09-30 微光口径事故的直接形态);若发现自己需要一条规则,那是自己的概念,先立权威文档再定义 | -| 引用落到对外承诺 | 跨文档链接只锚到对方文档明示的对外内容(事件、接口、规则条目),不锚其内部细节 | -| 依赖逐条列出 | 系统文档的「依赖与输出」节逐条列出本系统依赖的他人概念(规范名 + 链接)——这份清单就是删除概念时的影响面清单 | -| 引用必登记反向边 | 引用他系统概念时,在被引方的 registry 条目 `referenced_by` 里登记——影响面靠它机械列出,不靠全仓搜 | -| 链接断了也好读 | 引用处的句子在链接失效后仍通顺完整(写"变异规则见《地形变异》",不把半截语义挂在链接里) | -| 待办单点登记 | 全项目待办事项单点登记于 `design/gdd/06-待办清单.md`:系统文档的「待办」节只留指路存根,不得自建条目表;新增待办条目直接登记清单,裁决后改「状态」列留痕、不删条目 | - -**引用格式**:一律 Markdown 相对链接,指向文件、必要时带节锚点(例:`[地形变异 · 变异类型](systems/排雷循环/地形变异.md#变异类型)`)——机械可查,死链可被工具检出。 - -**删除概念 SOP**:① 查 registry 该条目的 `referenced_by`,得到影响面清单 → ② owner 文档删除概念 → ③ 纯引用方删链接即完事;机制被织入对方规则的,按清单逐处修订 → ④ 收尾跑一遍死链检查,全绿即干净。 - -**诚实边界**:机制耦合无法靠删链接消灭——别人的规则真的因你的概念而改变时,改内容不可避免。引用纪律保证的是:这类修改有一份现成清单(反向边 + 依赖节),不用事后全仓搜索。 - -## 9. 归档与事实源 - -- 旧文档里的概念写进现行文档时,必须翻译成现行术语与现行决策口径(例:雾格已从设计中移除,不得作为现行机制引用)。 -- registry 中 owner 仍指向旧 GDD 路径的条目,在对应新系统文档定稿后逐条改指新路径。 +## 7–9. 概念封装 / 引用纪律 / 归档与事实源——已独立成文 `design/dev/concept-conventions.md` ## 10. 会话记录纪律 -**active.md 定性:状态文件(2026-10-09 用户裁决;2026-10-10 用户再立:它是状态记录,不是工作日志——旧叫法废止)。** 根目录 `active.md` 是会话状态的唯一状态源,**每一行都必须在当下为真**;它不是历史档案——历史变更一律以 git 提交史为准(删除条目不销毁任何记录:`active.md` 自身的每个历史提交版本都完整可查)。只许写入三类内容:①当前状态快照(≤10 条滚动窗口);②未决面(进行中批次/待人闸/待裁点的指针);③当前迭代的滚动工作条目。禁止写入:已完结批次的历史叙述(归 git 与各权威文档)、待办裁决事项(归 `06-待办清单.md`)、跨会话教训(归记忆库);并行会话禁止将本文件整体复原/回退(2026-10-09 覆写事故规矩化)。退役规则:**用户确认任务完成时,清除当前会话写过的状态条目——状态清除即任务完成的证明,不留执行中痕迹(2026-10-10 用户立)**;条目完结判据=批次已入库+结论已进快照+未决面无条目指向它;迭代收口兜底删除已完结条目,状态记录超过 30 条必须清(2026-10-09 用户裁:每迭代收口清+30 条兜底)。 +**active.md 定性:状态文件——它是状态记录,不是工作日志。** 根目录 `active.md` 是会话状态的唯一状态源,**每一行都必须在当下为真**;它不是历史档案——历史变更一律以 git 提交史为准(删除条目不销毁任何记录:`active.md` 自身的每个历史提交版本都完整可查)。只许写入三类内容:①当前状态快照(≤10 条滚动窗口);②未决面(进行中批次/待人闸/待裁点的指针);③当前迭代的滚动工作条目。禁止写入:已完结批次的历史叙述(归 git 与各权威文档)、待办裁决事项(归 `06-待办清单.md`)、跨会话教训(归记忆库);并行会话禁止将本文件整体复原/回退。退役规则:**用户确认任务完成时,清除当前会话写过的状态条目——状态清除即任务完成的证明,不留执行中痕迹**;条目完结判据=批次已入库+结论已进快照+未决面无条目指向它;迭代收口兜底删除已完结条目,状态记录超过 30 条必须清。 -根目录 `active.md`(会话快照+批次状态记录)每条进度用完整的白话句子写清结论本身;条目写多长以读者能看懂为准,不设行数上限(2026-10-04 用户立规:能看懂比字数少更重要,原「每条 ≤3 行」约束废除——该约束曾迫使状态记录压缩成只有作者自己懂的自造缩略语,是文档黑话的繁殖地)。仍然禁止的只有两件:把定稿摘要、义务清单整段搬进条目(详情归各权威文档,状态记录只记结论);以及自造黑话——第 4 节用语纪律对状态记录同等生效。状态记录条目记裁决结论本身,不记中间文档文件指针(见第 11 节)。 +`active.md` 每条进度用完整的白话句子写清结论本身;条目写多长以读者能看懂为准,不设行数上限(能看懂比字数少更重要——行数压缩曾迫使条目使用只有作者自己懂的自造缩略语)。仍然禁止的只有两件:把定稿摘要、义务清单整段搬进条目(详情归各权威文档,状态记录只记结论);以及自造黑话——第 4 节用语纪律对状态记录同等生效。状态记录条目记裁决结论本身,不记中间文档文件指针(见第 11 节)。 -## 11. 文档生命周期:吸收即死(2026-10-01 用户立规) +## 11. 文档生命周期:吸收即死 文档分两类。**活文档**是唯一事实源,长期维护:GDD 树、art-bible 等定稿规范、registry、本规范、`design/gdd/06-待办清单.md`、`roadmap.md`。**中间文档**是脚手架,寿命=迭代寿命,不是项目寿命:批需求卡片、机检/验收过程报告、调研/审计报告、模拟读数、迭代计划书、目检清单。 @@ -183,28 +143,7 @@ | sim-data 白名单 | `sim-data/` 只保留 README、日志、分析工具 .py、现行 MC 对拍锚(显式清单)、设计文档 md;可再生原始数据(runsum/raw jsonl/逐局 CSV/report txt/样例输出)不入库 | | 出口清理项 | 每迭代出口检查单必含清理项:本迭代中间产物逐份核对(结论已吸收、未决已迁移)后删除 | | 暂存地非档案库 | `design/research/` 与 `design/qa/` 是中间文档的暂存地,不是永久档案库;入此两处的文件默认按本节规则到期即死 | -| 迭代实现报告(2026-10-10 立规,随三段开发流程) | 实现批收口的迭代级报告(`design/qa/iter-实现报告-<日期>.md`,一个迭代一份:各卡状态/代拍板追认单/GDD 反哺点节),属中间文档:GDD 反哺点未决先迁 `06-待办清单.md`,用户裁决落文吸收后按「证据只留最新」退役;替代原每卡出口报告 | -| 证据只留最新(2026-10-09 用户立规) | 测试证据(迭代实现报告/读数/截图/对比图)只保留最新一次迭代或最新一轮同类审计的版本——旧证据无参考作用,测试按状态不按历史;新证据落位后同批删除上一份;等人工检查的清单不受此限,过人闸后按本行退役 | +| 迭代实现报告 | 实现批收口的迭代级报告(`design/qa/iter-实现报告-<日期>.md`,一个迭代一份:各卡状态/代拍板追认单/GDD 反哺点节),属中间文档:GDD 反哺点未决先迁 `06-待办清单.md`,用户裁决落文吸收后按「证据只留最新」退役;替代原每卡出口报告 | +| 证据只留最新 | 测试证据(迭代实现报告/读数/截图/对比图)只保留最新一次迭代或最新一轮同类审计的版本——旧证据无参考作用,测试按状态不按历史;新证据落位后同批删除上一份;等人工检查的清单不受此限,过人闸后按本行退役 | -**删除方式**:按第 8 节删除概念 SOP 的口径执行——先查引用面(grep 文件名于上表阻塞域),改写或删除指路句,再删文件,收尾跑死链检查全绿。 - -## 版本历史 - -| 版本 | 日期 | 说明 | -|---|---|---| -| v1 | 2026-09-14 | 首版成文:整合用语纪律、文档形态纪律、两件套与树形文档体系、新骨架过渡口径,新增可读性第一纪律与系统文档骨架 | -| v2 | 2026-09-14 | 新增第 7 节引用纪律(跨文档高内聚低耦合:单点定义 / 规范名唯一 / 引用不转述 / 反向边登记 / 删除概念 SOP),原 7/8 节顺延为 8/9 | -| v3 | 2026-09-15 | 命名纪律补充:现行文档代号清偿完毕,子系统统一以中文规范名指代;英文代号对照表落盘 `design/gdd/02-系统清单.md`,旧代号仅限解读归档 | -| v4 | 2026-09-15 | 用语纪律正例去雾:第 4 节正例"剔除雾格后的可推理率"改为现行指标"实测可推理率"(原指标随雾格移除已删);规则文字与历史反例"非雾腿"、第 8 节雾格移除去向说明均不动 | -| v5 | 2026-09-15 | 新增第 7 节概念封装纪律(概念对象化建模:概念即对象 / 属性归属唯一 / 包含关系显式写 / 概念状态用枚举 / 附加物独立成对象 / 关系不吸内容),原 7/8/9 节顺延为 8/9/10,第 6 节骨架表与 CLAUDE.md 摘要的章节指针同步改指 | -| v6 | 2026-09-16 | 待拍板收编批:第 8 节引用纪律新增「待拍板单点登记」(待拍板事项单点登记 `design/gdd/06-待拍板清单.md`,系统文档只留指路存根,新增条目直接登记清单);第 6 节顶层文档表补入 `06-待拍板清单.md`,骨架表「待拍板」行改为指路存根口径 | -| v7 | 2026-09-16 | 06 清单改版(用户拍板):「待拍板」术语全仓改「待办」,清单更名 `design/gdd/06-待办清单.md`;清单内格式由四列表格改为「循环 → 系统 → 条目(四级标题)+ 粗体属性段(现状 / 归属 / 状态)」,条目解决后状态改"已解决(日期)"留痕;第 6 节顶层文档表与骨架表、第 8 节「待办单点登记」同步改指 | -| v8 | 2026-09-30 | **概念落位与口径携带条款(微光口径事故后补成,用户拍板)**:第 7 节概念封装纪律增「落位五要素」行(定义/作用对象与范围/生命周期/关联/状态缺一不立)与「无权威文档,不下定义」段(概念未落权威文档前,任何文档不得替它下定义,只许 06 登记「待落位」);第 8 节「引用不转述」行扩口径携带纪律(作用对象/范围/生命周期随句写全或显式指路,禁裸形容词复述) | -| v9 | 2026-10-02 | **文档生命周期条款(2026-10-01 用户立规「吸收即死」落文)**:新增第 11 节——中间文档寿命=迭代寿命,结论吸收进现行事实源即删、未决先迁再死、永不入库、引用面口径、台账记结论不记指针、sim-data 白名单、迭代出口清理项、design/research 与 design/qa 为暂存地非档案库;第 10 节补台账记结论口径;文首地位/适用范围两处过期路径修正(`docs/`→`design/dev/`、`production/` 会话记录→根 `active.md`) | -| v10 | 2026-10-04 | **台账去压缩条款(用户立规)**:第 10 节废除「每条 ≤3 行」——能看懂比字数少更重要;条目改用完整白话句子写结论,长度服从可读性;第 4 节黑话禁令对台账同等生效。起因:2026-10-04 黑话审计证实 ≤3 行压缩压力迫使台账条目使用自造缩略语(收口/落籍/在飞等约 15 个流程动词、530 条自造短语),并渗入正式文档;CLAUDE.md 规范导航表「会话进度记录」行同步改写 | -| v11 | 2026-10-04 | **第 4 节补强:自造词三形态禁令(用户令,黑话审计后)**:新增自造词三种固定形态禁令表(工作包代号 / 机制造词 / 流程造词,各带本仓真实反例与正确写法)+ 通行检验标准(读者 = 业内人但没读过项目历史,需要作者解释的词即不合格,展开才算改)+ 写后自查动作;同批 CLAUDE.md 硬性红线新增「用语红线」一行。起因:原第 4 节禁令过于抽象、执行失效(全仓 530 条自造短语),且未明确覆盖对话输出与状态记录命名 | -| v12 | 2026-10-09 | §9 摘除 design/archive/gdd-2026-09-14/ 归档列项(目录已删,2026-10-09 用户令旧档引用全量摘除);旧概念翻译与 registry 改指两条维持 | -| v13 | 2026-10-09 | §11 新增「证据只留最新」行(2026-10-09 用户立规——qa 存量清理批随批落文):测试证据只保留最新迭代/最新一轮审计版本,新证据落位即删上一份;待人清单过闸后同规退役 | -| v14 | 2026-10-09 | §1「与旧体系门禁的关系」段与现实对齐(文档正确性审查批·独立复核)——原文「gdd_lint 门禁已停用、现行文档不跑 lint」与现状矛盾:gdd_lint 现为机检三闸之一(与 doc_link_audit/doc_term_audit 并列,分级周期口径见 CLAUDE.md,2026-10-03 起分域批在役);lean 六条硬规则本身维持停用仅用于解读旧档;「可读性是第一内容质量门」定位不变,lint 定性为格式机检面 | -| v15 | 2026-10-10 | **迭代实现报告条款(2026-10-10 用户立规三段开发流程随批)**:§11 新增「迭代实现报告」行——实现批收口出迭代级一份实现报告(各卡状态/代拍板追认单/GDD 反哺点节),属中间文档,反哺点未决先迁 06、裁决落文后按「证据只留最新」退役,替代原每卡出口报告;「证据只留最新」行措辞同步换代。配套:GDD/art-bible 等设计权威文档实现批内一律不更新(文档更新必须经用户同意),反哺点经用户裁决另批落文——总规见 CLAUDE.md「三段开发流程」节与批次工作流第 12 条 v2 | -| v16 | 2026-10-10 | **用语纪律正面总则(2026-10-10 用户立规)**:§4 落「见名知意,所见即所得」——见名知意管名字(概念名/术语/文档与目录名本身说清所指,读者看到名字不用等解释就知道大概),所见即所得管句子(字面意思=规则的完整意思,有隐含前提就写进句子),并注明两句管语义透明、不与第 8 节指路存根冲突;§4 标题同步补八字总则。背景:用户已在用此尺裁用词(c50eef7「谓词」清除批自述「见名知意」),本批把现行做法成文 | +**删除方式**:按 `design/dev/concept-conventions.md` 第 2 节删除概念 SOP 的口径执行——先查引用面(grep 文件名于上表阻塞域),改写或删除指路句,再删文件,收尾跑死链检查全绿。 diff --git a/design/dev/test-conventions.md b/design/dev/test-conventions.md new file mode 100644 index 00000000..b688b508 --- /dev/null +++ b/design/dev/test-conventions.md @@ -0,0 +1,49 @@ +# 测试规范(Dungeon Sweeper) + +> 约束范围:`game/smoke/`、`game/tests/` 与一切场景探针的编写与验收。 +> 分工:测试**执行许可**(什么时候允许跑测试)归 CLAUDE.md「硬性红线·测试执行两入口铁规」;命令与工具清单归 CLAUDE.md「运行与验证」;本文管测试怎么写、怎么算合格。 + +**写任何测试前必须通读本文。** + +--- + +## 1. 测试总纲——"存在"必须证明"可达且正确" + +核心层验收标准通过不算有测试:GDScript 编译不查字典字段与时序,呈现层错误只在运行时暴露。 +测试必须证明功能可达(用户真的能用到)且行为正确(结果符合验收标准)。 + +## 2. 场景级探针标配 + +每新增一个可交互 UI 区域(视图/覆盖层/面板),必须配套场景级 headless 探针: +真实实例化场景 → 驱动真实输入路径 → 断言可见性与状态。 + +凡模态覆盖层,探针必须断言:打开后自身 visible 且遮挡物已隐藏(模态被遮挡 = 功能存在但不可达)。 + +## 3. 缺陷修复必须沉淀回归断言 + +每个缺陷修复必须在探针或冒烟中留下能抓住该缺陷的断言(例:旗动作耗尽 AP → 必须进入第 2 轮; +选用道具 → 库存态必须变 Used)。没有回归断言的修复视为未完成。 + +## 4. 提交前全量验证 + +交付前必须全绿:`smoke_all.gd` + 全部场景探针(ui_probe / ui_click_probe / ui_tune_probe)。 +行为探针使用随机化玩家行为(旗/停手/刷新/无效点击)——自动玩家不做的动作就是测试盲区。 + +## 5. 测试函数怎么写——验收清单条目的落码规范 + +需求卡片 §7「逐需求点验收清单」每一条都要落成可执行的验证;本文定统一写法,卡里定每批的具体内容(测什么/注入哪里)。写卡期查不出执行载体的条目=不可测,当场呈报,禁拖到实现期。 + +1. **执行载体五选一,逐条声明**:单元测试(`tests/run_all`)/冒烟断言(`smoke_all.gd` 对应场景段)/场景探针(`smoke/` 下 `*_probe`)/MC 同种子对拍/人工核对(仅限无法自动化的纪律类需求点,如命名锁定、数值占位)。行为类条目以自动化载体为主。 +2. **粒度与对应关系**:每条清单条目至少一个自动断言;多条条目可合用一个测试函数。断言失败消息末尾带编号尾缀〔卡短名 Vn〕(如〔秘宝批 V3〕)——断言与卡片清单可互相 grep 查找。 +3. **断言词汇按验证对象五选一**: + + | 词汇 | 适用场景 | + |---|---| + | 逐位相等 | 同种子下确定性公式与结算的精确对拍 | + | 区间/差值带 | 概率与平衡读数(MC 同种子配对比较,出带即红) | + | 快照比对 | 存档域结构、配置表行结构 | + | 重放 | 同种子断点回放、改前改后配对 | + | 状态/计数器断言 | 条件解锁、限次、充能——置数据→走路径→断计数值 | + +4. **调试注入两层(能力测试与流程体验两分法的落码面)**:自动化测试=测试代码直调核心层写口构造状态(直改数据表行/计数器/存档域,不经 UI、不走正常资源积累流程——冒烟现役做法);人工体验=DebugOverlay/DS_DEBUG 调试面,服务用户目检。清单条目的「怎么测」必须写到数据面粒度:改哪张表哪行、置哪个计数、调哪个核心写口。 +5. **换代批旧验证约束同生死**:删除旧数据行/旧实现代码的批次,必须同批摘除只验证旧实现的断言与护栏校验,由新断言替代——旧件断言残留=冒烟假绿来源;合并后冒烟全绿且全仓无旧件残留引用为证。