diff --git a/CLAUDE.md b/CLAUDE.md index 3ea69bfa..b9c4501b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -41,7 +41,7 @@ | 时机 | 权威文档 | |---|---| | 批次开工 / 流程纪律 | `design/dev/process-conventions.md`——worktree 铁律、五段流水线、批次清单、测试两入口与 MC/闸机细则、像素纪律 | -| 流水线段入口 | 技能对照——doc-design=文档设计/asset-ingest=美术录入/iter-plan=迭代编排(三者装于项目 `.zcode/skills/`)/req-card=写卡/iter=实现(此二者用户级 `~/.zcode/skills/`);登记不立技能;格式与状态机权威=`design/dev/doc-conventions.md` §12 | +| 流水线段入口 | 技能对照——doc-design=文档设计/asset-ingest=美术录入/req-card=写卡/iter-plan=迭代编排/iter=实现(五者均装于项目 `.zcode/skills/`);登记不立技能;格式与状态机权威=`design/dev/doc-conventions.md` §12 | | 写代码 / 改代码前 | `design/dev/code-conventions.md`——结构/契约/语言/数值/流程五类硬纪律(反例库 = 同目录 code-conventions-cases.md) | | 写测试 / 改测试前 | `design/dev/test-conventions.md`——探针标配 / 回归断言 / 全量验证 / 验收清单落码 / 变异验证 | | 写文档 / 改文档前 | `design/dev/doc-conventions.md`——白话写作 / 载体分工 / 用语 / 结构骨架 / 会话记录与生命周期 | diff --git a/design/dev/process-conventions.md b/design/dev/process-conventions.md index 62241bb8..64cd89f2 100644 --- a/design/dev/process-conventions.md +++ b/design/dev/process-conventions.md @@ -16,7 +16,7 @@ ## 2. 五段流水线 -一切要做的东西按五段流水线走:**登记 → 文档设计/美术设计(双轨)→ 写需求卡片 → 迭代编排 → 实现**。段间不自动流转,每段转进由用户发令;每段一个技能入口(doc-design/asset-ingest/iter-plan 装于项目 `.zcode/skills/`;req-card/iter 为用户级技能),登记不立技能(条目格式由流水线闸强制)。设计工作在会话内进行、用户主导、禁无监管自跑。 +一切要做的东西按五段流水线走:**登记 → 文档设计/美术设计(双轨)→ 写需求卡片 → 迭代编排 → 实现**。段间不自动流转,每段转进由用户发令;每段一个技能入口(五者均装于项目 `.zcode/skills/`:doc-design/asset-ingest/req-card/iter-plan/iter),登记不立技能(条目格式由流水线闸强制)。设计工作在会话内进行、用户主导、禁无监管自跑。 | 段 | 入口技能 | 产出 | 出入口铁律 | |---|---|---|---| diff --git a/design/gdd/06-待办清单.md b/design/gdd/06-待办清单.md index f02b7921..5cdc0fab 100644 --- a/design/gdd/06-待办清单.md +++ b/design/gdd/06-待办清单.md @@ -547,7 +547,7 @@ **归属**:全工程(排雷循环/战斗循环/冒险循环/呈现层/数据表/冒烟测试均触及;主责=术语表裁定执行) -**状态**:待写卡 +**状态**:已写卡(design/research/需求卡片-代码术语刷新批-2026-10-18.md)+已编迭代 31 --- @@ -620,3 +620,34 @@ **归属**:game/smoke/screen_flow_probe.gd(探针自救面)与 tools/probe_gate.sh(跑批隔离面)——测试基建 **状态**:待写卡 + + +--- + +#### 计数器寿命域未统一(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` 实际承担「按关重置」语义(`entities.yaml:16`)。`effect_engine.gd:119-121` 自称「生命周期四态」(跨战持久/按关重置/新冒险清零/断点保留),却未按枚举落地。**后果**:任何带寿命权重的核算(期望收益/强度摊销/「每 X 一次」折算)无法在数据层进行,须逐条读注释或读清除侧代码。**用户已裁:本批不动寿命域**,完美保险按现役 `domain=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,命名待用户定);⑤`grant_segment.gd` 硬编码 `_fx_insurance` 改订阅式——**按用户指定做法**:新增自有累加计数,判定时取「误标总数 − 豁免数」得有效数,**不改写既有 `_perfect_hit_false`、不拦截事件**(原方案的回退式与拦截式均已否决)。测试面 `feat_vouchers_test.gd` V9/V16 同步。玩家面术语统一用「完美封印」、不用「完美排雷」(命名纪律见奇物.md v3.15)。 + +**归属**:game/ 代码与数据表(走独立 worktree 批) + +**状态**:待写卡 + +--- + +#### 2026-10-18 冒记案遗留待裁两项(2026-10-18 登记,来源=审计发现,设计面=文档轨) + +**现状**:2026-10-18 考古确认两处「判据推演被写成事实记载」,均缺用户裁断的独立记录源——①`entities.yaml:629` 与奇物.md §1.1「专长凭证也归专长,不归资源」:引入于 10-05 `d6c13809`,该提交信息「用户明确」小节仅覆盖**机制**(非 Boss 渠道给门票、拿到即开、限购、保底),**不覆盖归类**;用户 2026-10-18 明确表示不认同此归类。**本批未删**,等正式裁定后再动。②奇物.md §1.3 判据句「资源成员=**转换源**凭证」:引入于 10-08 `6e054466`,该提交信息无「用户裁」字样,而同批头注假托的「2026-10-07 用户裁准写入文档」实为当日用户裁的是**池结构案D**。**本批只删了头注中那句失实的时间-裁断陈述,判据句本身未动**,待裁定后连同 §1.3 一并重写。甄别方法(git log -S 追引入提交 → 核对提交信息管辖范围 → 找独立第二记录源)已记入项目记忆。 + +**归属**:奇物.md §1.1/§1.3、entities.yaml:629 + +**状态**:待裁决 diff --git a/design/gdd/07-体验验证清单.md b/design/gdd/07-体验验证清单.md index e29257e9..da1bdfcc 100644 --- a/design/gdd/07-体验验证清单.md +++ b/design/gdd/07-体验验证清单.md @@ -11,9 +11,9 @@ > **✅ 已核销(2026-10-14)**:用户实机目检回报完成,未呈报问题(qa 收尾批)——下五项同批核销。 - **Boss 专长三选一呈现**:非末关通关停点候选=全专长新 29 件(按档配比加权——普通打底/稀有稀缺);旧「提升三选一」属性件不再出现于通关渠道;回血读数照旧随载荷。 -- **曝光槽三卡观感**:奖励节点/商店三选一=2 格全池+1 格优秀档以上子池(子池空回退全池);新凭证四件(储备金袋/同调电池/时沙/完美保险)稀有档投放观感。 +- **曝光槽三卡观感**:奖励节点/商店三选一=2 格全池+1 格优秀档以上子池(子池空回退全池);新凭证四件(储备金袋/同调电池/时沙/完美保险)稀有档投放观感〔**其中两件已于 2026-10-18 用户裁退出本池**:同调电池删除、完美保险改归专长——该项投放观感对这两件不再适用,余储备金袋/时沙仍有效〕。 - **卡面文案与稀有度档位显示**:新 29 件专长 display_name/desc 直读行字段(封印/陷阱风味系命名);四级档位(普通/优秀/稀有/传说)在卡面档位显示位是否正确渲染。 -- **同调电池选件面**:拾取同调电池后的充能分配交互(choose_battery_target 核心面已落,呈现层选件窗=本批登记观测——若呈现缺窗,登记缺陷回反哺点)。 +- **同调电池选件面**〔**2026-10-18 整条注销**——观测对象同调电池经用户裁删除,不复存在;注销前状态=核心面 choose_battery_target 已落但呈现层选件窗从未接线,该项「若呈现缺窗则登记缺陷」的使命随件删终止〕:拾取同调电池后的充能分配交互(choose_battery_target 核心面已落,呈现层选件窗=本批登记观测——若呈现缺窗,登记缺陷回反哺点)。 - **HUD 特性段逐件行**〔2026-10-12 呈现修复批换代——僵尸呈现已修:聚合行退役改逐件行「件名 ×N」、卡面摘族名〕:验修复后 C 区/关卡页逐件行可读、卡面=件名+效果摘要无任何分类字样(原「前对照取证」使命已完成,git 史 33d65ce 留痕)。 diff --git a/design/gdd/systems/冒险循环/奇物.md b/design/gdd/systems/冒险循环/奇物.md index 9e431e89..b0f1720a 100644 --- a/design/gdd/systems/冒险循环/奇物.md +++ b/design/gdd/systems/冒险循环/奇物.md @@ -104,6 +104,8 @@ 惊巢反制=退役进素材库(不迁入)。 +**资源类迁出件(2026-10-18 用户裁)**:完美保险自资源类迁入专长——理由:它给的是**规则豁免**而非可调动的余量(§1.1 判据「给规则的是专长」),效果=本场首次封印落空不计入完美封印判定。旧「资源类成员」归类系 2026-10-08 框架批写入、无用户裁断支撑,随本次改判注销。专长行的触发器规格与代码实现(含效果引擎词表扩签)归独立批,见 06 登记。 + ### 扩签登记(迭代 20 实装已承载——2026-10-12 追认④写入文档换代) - **落地结果**:事实候选 10 条中 6 条落 FACTS 词位(边缘格判定/空白连锁判定/单次伤害量/被挖格当时有封印印记/雷罚伤害量/生命比例),4 条改道 adventure 域计数器(类型集合计数器/本轮挖格花费/本轮开格数/本轮踩雷数计数器——跨事件累积量走计数器+value_event 比较,不占 fact 词位,T0 定架构);停手事件已落(dig_stop);实现随裁补位=battle_won 事件(战地包扎所需,登记未列)、mod_eq 算子(周期触发)、hp_ratio(百分比 int 口径)等 3 项事实、新效果类型 7 项。 @@ -116,17 +118,17 @@ ## 资源(重设计·基础框架 v1) -> 本节是资源分类的现行事实源(2026-10-07 五件新凭证用户裁准写入文档)。资源成员 = **转换源**:不是资源本身,是「到手即结算成独立资源或系统数值的凭证」——凭证加完消尽,被写入的账各有自己的寿命档位。判据句与归类方法见 §1.3/§1.4。**新凭证已随迭代 20 专长实装批落表(2026-10-11,新 5+留任 2)。** +> 本节是资源分类的现行事实源。资源成员 = **转换源**:不是资源本身,是「到手即结算成独立资源或系统数值的凭证」——凭证加完消尽,被写入的账各有自己的寿命档位。判据句与归类方法见 §1.3/§1.4。**新凭证已随迭代 20 专长实装批落表(2026-10-11);2026-10-18 用户裁削两件后,现行成员=新 3+留任 2(同调电池删除、完美保险归专长——见版本历史 v3.18)。** -### 凭证件表(新 5 + 留任 2;代号制命名归用户;稀有度档、配额与面值数值归调参批) +### 凭证件表(新 3 + 留任 2;代号制命名归用户;稀有度档、配额与面值数值归调参批) + +> **2026-10-18 用户裁削两件**:**同调电池**删除——秘宝是「局外同调件」、冒险中零更换途径,与 `cf04bd66` 撤换装券/删回能器同一原则(且 UI 层从未接线选件入口);**完美保险**迁出资源类改归专长——它给的是规则豁免,不是余量,见 §1.1 判据。两件原职责账(秘宝充能/完美资格)同步自 §1.3 账清单注销。 | 代号 | 写进哪本账(寿命档) | 一句话 | 备注 | |---|---|---|---| | 刷新券 | 刷新存量账(冒险级) | 存量刷新次数 +1 | 语义=存量加仓(已裁);实现依赖刷新件写错账修复(同批) | | 储备金袋 | 储备池 RAP(节点级) | 储备池 +N | 给停手/刷新雷图经济加燃料;战斗结束清零系既有语义,兼容 | -| 同调电池 | 秘宝充能账(冒险级) | 一件已装配主动秘宝使用次数 +1(本次冒险,玩家选哪件) | 跨层写秘宝抽屉;充能冒险开始重置,兼容 | | 时沙 | 下一战首轮 AP 队列(拾取挂账,兑付即消尽) | 下一战首轮 AP +2 | 一次性节奏件;与「AP 上限+1」(属性轴)不撞——一个改池子、一个改上限(落法=hero_ap_bonus 既有通道,2026-10-12 追认⑦回写;拾取时战斗在途同样等下一战首轮) | -| 完美保险 | 完美排雷资格(节点级) | 本战下一次标错不破坏完美资格 | 资格保护凭证 | | 小金币袋 | GP 钱包(冒险级) | (留任)+20 / +50 | 计价物不自售维持(不进商店) | | 应急口粮 | 生命账(冒险级) | (留任)回复 +6 | 在商店内(默认原则) | @@ -220,13 +222,13 @@ #### 1.3 资源:转换源凭证 -资源这一类装的是"不抬高战斗属性、也不改规则,但让你更有余地"的东西。成员现行事实源=本文件「资源(重设计·基础框架 v1)」节的**凭证件表(新 5+留任 2)**;旧枚举四项的去向:行动点上限归属性值提升轴(见 1.2)、刷新次数由刷新券替代、GP 与回复留任为小 GP 袋/应急口粮。 +资源这一类装的是"不抬高战斗属性、也不改规则,但让你更有余地"的东西。成员现行事实源=本文件「资源(重设计·基础框架 v1)」节的**凭证件表(新 3+留任 2)**;旧枚举四项的去向:行动点上限归属性值提升轴(见 1.2)、刷新次数由刷新券替代、GP 与回复留任为小 GP 袋/应急口粮。 **资源为什么单独成一类**:它的成员不满足"抬高战斗属性"(那归属性值提升),也不满足"改写规则"(那归专长),但玩家拿到时的感受是一致的——"我能做的事变多了"。把它们跟属性提升混在一起,会让"加了多少攻击"这种可度量的提升和"多一次重抽"这种不可度量的余地摆在同一张候选卡上,玩家没法比。即时兑付的金币与回复同留本类、不独立成第四类(2026-10-05 用户定)——判据与资源完全同源,拆出去只会让读者多查一张表。 **判据句("资源"这个词太泛,这句是唯一的界定凭据)**:资源成员是**转换源**——不是资源本身,而是「到手即结算成独立资源或系统数值的**凭证**」,凭证加完消尽;被写入的账(GP 钱包/刷新存量/储备池/充能/时沙挂账/资格)各有自己的寿命档位。拿不准一项该归哪类时问三句:它进不进角色自己的属性数值(进→属性值提升);它改不改规则(改→专长);都不是、而是某本系统账上多出来的一笔一次性加仓的,归资源。 -**资源类内部的异质性(统一表述)**:凭证全部即时消尽——不存在「持有凭证」这种状态;异质性不在凭证上,而在**被写入的账的寿命**上:GP 钱包 / 生命账 / 刷新存量 / 秘宝充能 = 冒险级,储备池 / 完美资格 = 节点级,时沙挂账 = 至下一战首轮兑付(账清单对齐「凭证件表(新 5+留任 2)」节;「AP 上限」已归属性值提升轴,见 1.2)。登记此节防止把凭证当成会持续生效的东西去结算。 +**资源类内部的异质性(统一表述)**:凭证全部即时消尽——不存在「持有凭证」这种状态;异质性不在凭证上,而在**被写入的账的寿命**上:GP 钱包 / 生命账 / 刷新存量 = 冒险级,储备池 = 节点级,时沙挂账 = 至下一战首轮兑付(账清单对齐「凭证件表(新 3+留任 2)」节;「AP 上限」已归属性值提升轴,见 1.2)。原在册的「秘宝充能」「完美资格」两账随 2026-10-18 两件裁削注销——`attune_charges` 账本本身仍为秘宝基础设施保留(迭代 11,主动件充能每冒险重置),本次只删奇物侧写它的入口。登记此节防止把凭证当成会持续生效的东西去结算。 #### 1.4 分类判据 @@ -428,7 +430,7 @@ | 专长定义行(标识 / 显示名 / 稀有度 / 效果说明 / 订阅行〔订阅哪个事件 on / 什么条件 when / 什么效果 do〕) | 各字段封闭枚举,行键白名单封闭;事件 / 效果类型 / 条件事实 / 算子四词表封闭(效果引擎单一事实源);稀有度档=新四级(普通/优秀/稀有/传说),schema 字段双脱钩(字段在、设计面按档配比加权) | `game/data/tables/feats.tres` | | 专长凭证(出现概率 / 配额 / 限购次数 / 保底计数阈值) | 整数,四参数全 provisional | 已入表(迭代15② 凭证行——`shop.tres` + `adventure_table.gd`) | | 属性值提升种类 | 封闭三项:生命上限 / AC / 攻击,扩项走文档修订 | `game/data/schemas/adventure_table.gd` | -| 资源种类 | 种类现行事实源=「凭证件表(新 5+留任 2)」节;凭证已入表(迭代15②) | 同上 | +| 资源种类 | 种类现行事实源=「凭证件表(新 3+留任 2)」节;凭证已入表(迭代15②) | 同上 | | 稀有度档位 | 封闭四级(普通 / 优秀 / 稀有 / 传说);配额是结构锚,改总量须重新拍板而非调参 | 同上 | | 各分类种类 × 档位的配额与值 | 整数 | `game/data/tables/adventure.tres` | | 专长获取的全局限量 | 整数(一局内可获得的次数上限) | 同上 | @@ -491,3 +493,4 @@ | **v3.15** | 2026-10-11 | **专长件第一版命名批(用户裁——对外命名纪律:无「雷」无「插旗」,插旗对外=封印、危险格对外风味=地下城陷阱/怪物巢穴;「扫雷插旗」系内部开发用语、对外=探索/挖掘地下城)**:九件代号换代——插旗系:旗语回响→**封印回响**/猎旗手→**封印匠**/铁旗→**封印桩**;踩雷/受伤系:爆芯→**陷阱本能**/连爆→**连环陷阱**/爆心冲击→**陷阱爆发**/雷蜜→**血蜜**;跨族桥:引信标定→**破封一击**;迁入登记:标中殉爆→**封印爆裂**;示警烟火/疼痛记忆/保险丝/见血开窍/石肤/背水/爆破会计等保留(无雷/旗字);纪律登记=术语表新增「对外命名纪律」节(v1.6);版本历史行引用旧代号系留痕不动;命名纪律试例=件名,后续全部对外命名(显示名/UI 文案)同尺 | | **v3.16** | 2026-10-12 | **迭代 20 反哺落文批(用户令「先回写 GDD」——追认单①裁决齐,06 追认结果条承载裁决记录)**:①设计原则新增**落行注记**:「每第 N 次/积满触发」预评估落行=N−1(when 先于 do 读计数器现值,例:地质学家 eq 3/封印匠 mod_eq ref 2);②疼痛记忆件表「下场战斗」→「下一次攻击」(2026-10-12 用户定性笔误,无需 battle-gate 面);③弃图兑换落法回写=停手后首次攻击全额附加、用后清零、多攻击不拆分;④血税件表补生效时点(均**下一战起生效**——战末汇入冒险加算区,战界重建契约所致滞后一战)+账列换代双向同账细则;⑤时沙落法回写=下一战首轮 AP 队列兑付(hero_ap_bonus 既有通道),§1.3 判据句与异质性账清单「当前 AP=回合级」随迁「时沙挂账=至下一战首轮兑付」;⑥扩签登记节换代为实装承载记录(10 候选=6 fact+4 计数器改道/dig_stop 落/battle_won+mod_eq+hp_ratio 等随裁补位/新效果类型 7/rewrite_board 除名、清图事件继续暂缓);⑦专长/资源两节引言「新框架实装批落地前」过渡句随批落地 expiry 换代(29 行=基础 27+迁入 2/凭证新 5+留任 2 已落表);⑧流派口径澄清落档=**对外永不显示、对内保留事件族五系划分**(v2.9 作废所指=流派作玩法机制非对内划分本身,2026-10-12 用户重申——设计原则第 2 条原文已符,正文零改动);待办=血税卡面 desc(feats.tres)补「下一战起生效」系代码侧一行改,另行小批 | | **v3.17** | 2026-10-15 | **简明技术中文用语规范批(用户令):词面修正 7 处**——「不得」→「禁止」3 处(信息红线条、代码词族 reward_* 句、验收第 6 条);「若干」→写具体数值 2 处(核心循环位置图「三关串联」、生命周期表出现行「3 个候选」);「收口」改写 2 处(§1.3 判据句「收口凭据」→「界定凭据」、§2.1 悬案句→「完成裁决」)。机制与数值零改动 | +| **v3.18** | 2026-10-18 | **凭证件裁削批(用户逐裁——①同调电池删除、②完美保险改归专长)**:①凭证件表计数「新 5+留任 2」→「**新 3+留任 2**」——同调电池整行删除(秘宝=局外同调件、冒险中零更换途径,与 2026-10-11 撤换装券/删回能器同一原则,且 UI 层从未接线选件入口);完美保险整行迁出资源类改归专长,理由=它给的是规则豁免而非可调动的余量(§1.1 判据),经文记入迁入登记节。②§1.3 异质性「被写入的账」清单注销「秘宝充能」「完美资格」两账;`attune_charges` 账本本身仍属秘宝基础设施保留(迭代 11),本次只删奇物侧写它的入口。③受影响的计数与指路同步换代:§1.3 引言、凭证件表标题、调参表「资源种类」行。④**一处失实记载订正**:资源节头注原写「2026-10-07 五件新凭证**用户裁准**写入文档」——当日用户所裁为池结构案D,未作此归类裁定,该句删除(「资源成员=转换源」判据句本身本批不动,是否复裁归 06 在册)。⑤本批**代码侧零改动**,归独立批:`CURIO_KINDS` 删两枚、`TIER_QUOTAS` rare 9→7 与总量 104→102(结构锚,用户已裁**净删**)、`feats.tres` 增完美保险行、效果引擎扩签一种效果类型、`grant_segment` 硬编码改订阅式(误标总数减豁免数得有效数,不改写既有计数值)。 | diff --git a/design/registry/entities.yaml b/design/registry/entities.yaml index e3f5d2c8..ea5975a8 100644 --- a/design/registry/entities.yaml +++ b/design/registry/entities.yaml @@ -630,7 +630,7 @@ entities: boundary: 判据走生命周期——**一次冒险内获得、冒险收束即清零的是奇物;跨冒险跟着你走的是秘宝**。奇物永不进同调位,秘宝永不进当局随机渠道;与元进度天赋树两层互不代位 data_sources: feats.tres(专长定义行——效果声明=triggers 订阅行〔订阅哪个事件 on / 什么条件 when / 什么效果 do〕,旧挂点+效果字典形态 2026-10-06 内容数据驱动扩展批退役)/ adventure.tres(属性值提升与资源的种类配额与值)/ shop.tres(货架取舍) effect_declaration: **效果行为=事件订阅(2026-10-06 内容数据驱动扩展批换代)**——事件/效果类型/条件事实/算子四词表封闭于效果引擎 `game/core/effect_engine.gd`(事件 16 发射点 / 效果类型 24 / 条件事实 9 / 算子封闭;四词表出域=加载期校验致命);组合规则六族(加法/乘法/任意真/按序改写/按序消耗/即时执行)为效果类型必填属性;遍历序=数据表声明序写死保种子复放;订阅重建=每战开始从持有集/装备集重建(中途获得下一战生效) - iter20_rebuild: **专长重设计换代(2026-10-11 专长实装批迭代 20)**——feats.tres 29 行(基础 27+迁入淬毒刃纹/封印爆裂,卡文 §10.4 口径)整表替换旧 27 件〔素材库表二〕;rarity 四级(普通 12/优秀 9/稀有 8/传说 0)直映射令牌档+cap 已拿上限字段;**流派标签/档位激活机制退役**(奇物.md v1「不设流派标签不设档位」——ARCHETYPES/FeatsEngine 档位质变摘除,charge 档二不可达缺陷随框架退役消解);词表扩签=事件 18(+dig_stop/battle_won)/效果类型 30(+heal/ac_bonus/damage_reduce/bonus_delta/blast_scaled/preview_area/target_attack_bonus,rewrite_board 除名)/事实 18(+生命比例等 9)/算子 +mod_eq;池结构案D=四级档位 70/25/9/0=104+曝光槽 2+1+概率上限解耦(案②令牌池+提前退役 cap)+Boss 按档配比加权抽取;凭证五件入池(刷新券 F-1 修复/储备金袋/同调电池/时沙/完美保险);adventure 域计数器跨战账本(domain 键+counters_export/seed) + iter20_rebuild: **专长重设计换代(2026-10-11 专长实装批迭代 20)**——feats.tres 29 行(基础 27+迁入淬毒刃纹/封印爆裂,卡文 §10.4 口径)整表替换旧 27 件〔素材库表二〕;rarity 四级(普通 12/优秀 9/稀有 8/传说 0)直映射令牌档+cap 已拿上限字段;**流派标签/档位激活机制退役**(奇物.md v1「不设流派标签不设档位」——ARCHETYPES/FeatsEngine 档位质变摘除,charge 档二不可达缺陷随框架退役消解);词表扩签=事件 18(+dig_stop/battle_won)/效果类型 30(+heal/ac_bonus/damage_reduce/bonus_delta/blast_scaled/preview_area/target_attack_bonus,rewrite_board 除名)/事实 18(+生命比例等 9)/算子 +mod_eq;池结构案D=四级档位 70/25/9/0=104+曝光槽 2+1+概率上限解耦(案②令牌池+提前退役 cap)+Boss 按档配比加权抽取;凭证五件入池(刷新券 F-1 修复/储备金袋/同调电池/时沙/完美保险——**2026-10-18 用户裁削:同调电池删除、完美保险改归专长,现行在池三件**;本行 104 总量与 TIER_QUOTAS 读数仍为代码现值,改数随独立代码批同步);adventure 域计数器跨战账本(domain 键+counters_export/seed) charge_defect: **charge 档二不可达登记(T7 奇物批迭代15②——数据缺陷留痕,白名单4授权「只登记不硬补」)**:feats.tres 现行 charge 标签仅 3 件(<4),档二激活要求同标签 ≥4 件——charge 流派永远达不到档二,即使获取次数无限。补哪几件系内容裁决,转独立内容批(硬补占位件已否决);档二可达性复裁=第四关内容批落地后实测(C2 待裁点)。 pool_architecture: **池架构=总池-渠道子集(多级缓存形,用户 2026-10-05 裁 T6 时确立)**:总池=单一令牌库(TIER_QUOTAS 70/25/3=98 + 专长活行追加);三渠道按分类白名单从总池取**子集视图**(关底 Boss 击败=只出专长子集;奖励节点/商店=属性值提升+资源子集,专长只以门票形态出现)——渠道不各建物理池,白名单在候选视图层生效(T4 过滤式)。配额挤占重裁:heal rare 5→3、refresh rare 0→2(方案B,总量 98 锚不变;用户裁「渠道从总量里拿子集」时同步裁)。 refresh_boundary: **刷新次数边界写死(T6 奇物批迭代15②——防后续混淆结算)**:「商店独立刷新机制」(shop_refresh_free/shop_refresh_cost_base/shop_refresh_cost_curve 三旋钮——进店后的免费次数+GP 付费刷新)系**商店自身服务**,作用对象=货架重抽;奇物 refresh 件(资源类成员,作为奇物授予的重抽次数)作用对象=**三选一界面**(兑付即 _attune_refresh_x 增量,X 余量=三选一重抽次数),不进加算区(§2.2 加算区四轴不含它)。两者不是一回事,禁止混算。 diff --git a/design/research/需求卡片-专长实装批-2026-10-11.md b/design/research/需求卡片-专长实装批-2026-10-11.md index 6aa5be0a..2d926218 100644 --- a/design/research/需求卡片-专长实装批-2026-10-11.md +++ b/design/research/需求卡片-专长实装批-2026-10-11.md @@ -18,7 +18,7 @@ 5. `game/data/tables/treasure_items.tres:76,111` 淬毒刃纹/封印爆裂(原标中殉爆)两行在役待迁(迁出即删)。 6. 冒烟基线 840 项 0 失败(design/qa/iter19-card0 出口报告);MC 链=adventure_monte_carlo.gd+analyze_playtest.py 聚合。 7. 06 在册:秘宝实装批条目(③专长侧联动由本卡承载)、生命比例扩签前置条、旧 MC 行为锚作废重锚归数值批条。 -8. 秘宝充能账在役(attunement.gd)——凭证件「同调电池」的跨层写入目标账已存在,不依赖秘宝实装批。 +8. 秘宝充能账在役(attunement.gd)——凭证件「同调电池」的跨层写入目标账已存在,不依赖秘宝实装批。〔**2026-10-18 注**:同调电池经用户裁**删除**,本条前提对后续批不再成立;`attune_charges` 账本本身作为秘宝基础设施保留〕 ## 3. 设计契约(违反即返工;🔴 触碰=L3 停机呈报) @@ -57,7 +57,7 @@ | T1 | 效果引擎词表扩签:9 条新事实+生命比例+停手挂点+新效果类型(heal/直伤/AC 状态/减伤等按 27 件声明清单)+加载校验同步 | 1.5-2d | | T2 | 池结构案 D 实装:令牌语义+曝光槽 2+1+子池回退+概率上限解耦落地+adventure.tres 四级配额表重构(70/25/3→四级) | 1.5-2d | | T3 | 专长数据行换代:feats.tres 旧 27 行删除+新 27 行订阅行重建(含淬毒刃纹/封印爆裂自 treasure_items 迁入) | 1.5d | -| T4 | 凭证件实装:新 5 件数据行与兑付路由(刷新券先行 F-1 修复/储备金袋 RAP/时沙 AP/完美保险/同调电池跨层写充能账〔在役〕)+留任 2 件改名迁移+行动点上限归属性轴 | 1.5-2d | +| T4 | 凭证件实装:新 5 件数据行与兑付路由(刷新券先行 F-1 修复/储备金袋 RAP/时沙 AP/完美保险/同调电池跨层写充能账〔在役〕)+留任 2 件改名迁移+行动点上限归属性轴 | 1.5-2d | | T5 | Boss 兑付面换代:通关提升三选一→专长三选一+回血(专长候选按档配比加权抽取;呈现层复用;奖励节点/商店不动)——Q1 已裁换代 | 1-1.5d | | T6 | 件级跨事件状态账:攒层/计数类件账本承载(T0 结论落地) | 1d | | T7 | 断点存档扩容:已拿计数器/新账面/池状态进断点附随件+存档键白名单登记 | 0.5-1d | @@ -88,7 +88,7 @@ | V6 | §1②(令牌语义) | 令牌=出现次数上限三态:拿了消耗(选中摘牌单点 adventure_runner.gd:448-457)、没拿回池(未选候选再次可现)、只刷出不计次数 | 冒烟。注入=直改 _curio_deck 构成+直调 pick_curio | 自动闸 | T2 | | V7 | §1②(曝光槽 2+1+子池回退) | 三选一呈现=2 格全池+1 格优秀档以上子池;高档子池空该格回退全池;池空走同族兜底;凭证不进子池(独立计数体系) | 冒烟。注入=直改 _curio_deck 档位构成(清空高档构造回退、清空全池构造兜底)后直调候选抽签面 | 自动闸 | T2 | | V8 | §1②(概率与上限解耦) | 每成员概率位与已拿上限 cap 两属性独立可设:改 cap 不动概率、改概率不动 cap;cap 只在拿了才计、刷出不计 | 冒烟/单元。注入=直改表行 cap 字段+直调兑付写口计数对读 | 自动闸 | T2 | -| V9 | §1(凭证五件路由) | 新 5 件兑付路由逐件断言(附表 B):刷新券→刷新存量账、储备金袋→RAP、时沙→当前 AP 池、完美保险→完美资格标记、同调电池→attune_charges 充能账(adventure_runner.gd:79 账本在役,玩家选件交互面) | 冒烟+单元。注入=直调 _apply_curio_pick 各 kind(adventure_runner.gd:411-444 路由面) | 自动闸 | T4(附属表=7.4) | +| V9 | §1(凭证五件路由) | 新 5 件兑付路由逐件断言(附表 B):刷新券→刷新存量账、储备金袋→RAP、时沙→当前 AP 池、完美保险→完美资格标记〔**2026-10-18 改归专长**,本路由作废〕、同调电池→attune_charges 充能账〔**2026-10-18 删除**,本路由作废〕(adventure_runner.gd:79 账本在役,玩家选件交互面从未接线) | 冒烟+单元。注入=直调 _apply_curio_pick 各 kind(adventure_runner.gd:411-444 路由面) | 自动闸 | T4(附属表=7.4) | | V10 | §1(留任 2 件迁移+AP 上限归属性轴) | 小金币袋/应急口粮改名迁移后路由与值不变(GP 钱包/当即回血);行动点上限自资源配额迁入属性轴(bonus 四轴 ap 落点 adventure_runner.gd:60 既有承载) | 冒烟。注入=直调 _apply_curio_pick+读加算区 | 自动闸 | T4 | | V11 | §1③(Boss 通关=回血+专长三选一) | 非末关通关恰一次发出 curio_choice_presented(adventure_runner.gd:44):载荷含回血读数、候选全为专长;末关通关不发;奖励节点与商店兑付面零变化;旧提升三选一通道摘除后候选零非专长令牌混入 | 冒烟。注入=auto_player 驱动至通关停点+直读停点载荷 | 自动闸 | T5 | | V12 | 奇物.md v3.1 档配比(契约 7 形态面) | Boss 三选一候选按档配比/加权抽取:同种子批量抽样各档出现频率出带(区间带,带=声明配比±容差) | MC 同种子对拍。注入=直调候选抽取面批量取样 | 自动闸 | T5 | @@ -144,9 +144,9 @@ |---|---|---|---| | 刷新券 | 刷新存量账(冒险级)+1;到手即结算消尽 | 不进持有集不进加算区;依赖刷新件写错账修复(F-1)同批落地 | 写进旧 _attune_refresh_x 账(写错账复发);可囤积 | | 储备金袋 | 储备池 RAP +N(节点级) | 战斗结束清零系既有语义 | 写 GP 钱包;跨节点残留 | -| 同调电池 | 已装配主动秘宝使用次数 +1(玩家选哪件,本次冒险) | 充能冒险开始重置(兼容);跨层写秘宝充能账 attune_charges | 自动替玩家选件;写当局加算区 | +| 同调电池〔**2026-10-18 删除**〕 | 已装配主动秘宝使用次数 +1(玩家选哪件,本次冒险) | 充能冒险开始重置(兼容);跨层写秘宝充能账 attune_charges | 自动替玩家选件;写当局加算区 | | 时沙 | 下轮 AP +2(回合级) | 一次性节奏件;只改池不改上限 | 抬 AP 上限(与属性轴混账);当轮即时生效 | -| 完美保险 | 本战下一次标错不破坏完美资格(节点级) | 只保一次;节点级 | 保护第二次标错;跨节点携带 | +| 完美保险〔**2026-10-18 改归专长**〕 | 本战下一次标错不破坏完美资格(节点级) | 只保一次;节点级 | 保护第二次标错;跨节点携带 | | 小金币袋(留任) | GP 钱包 +20/+50 | 计价物不自售(不进商店货架) | 出现在商店货架;进持有集 | | 应急口粮(留任) | 生命账当即回复 +6 | 在商店内(默认原则);封顶生效上限 | 进持有集;超上限回复 | diff --git a/design/research/需求卡片-代码术语刷新批-2026-10-18.md b/design/research/需求卡片-代码术语刷新批-2026-10-18.md new file mode 100644 index 00000000..9aa64a98 --- /dev/null +++ b/design/research/需求卡片-代码术语刷新批-2026-10-18.md @@ -0,0 +1,314 @@ +# 需求卡片:代码术语刷新批(flag→seal+中文禁用词清扫) + +- 版本:**v1.3**(2026-10-18 卡片冲突修订批:补「设计事实源」声明;§5 同步义务由「机械面随批」改为反哺点清单(对齐 req-card §6/§7 2026-10-17 改口径);T3.1 补 `flag_missed`→`seal_missed` 全链;新增与卡② 的命名接续契约。历史:v1.2 grilling 复核 Q4–Q8 全裁;v1.1 Q1–Q3 全裁) +- 来源: + - [06-待办清单](../gdd/06-待办清单.md)「代码术语刷新批——禁用词全库清扫+flag→seal 标识符重命名」(2026-10-18 登记,工程直入) + - 用户裁定(2026-10-18,记忆 `project-terminology-rulings-20261018.md`) + - 审计报告:[代码术语审计报告-2026-10-18](../qa/代码术语审计报告-2026-10-18.md) +- 归属:全工程(排雷循环/战斗循环/冒险循环/呈现层/数据表/冒烟测试);术语权威=[术语表](../gdd/术语表.md) +- 排期:**已编入 roadmap 迭代 31**(2026-10-18 用户确认;卡片状态=已编入,开工门=U0) +- **设计前置声明**:本卡属**重构/工程债**类,凭 2026-10-18 用户裁定与审计报告代码级证据直接写卡,跳过设计轨。 +- **设计事实源**(req-card §2 三选一之③工程直入证据指认,2026-10-18 立规;v1.3 补声明):[代码术语审计报告-2026-10-18](../qa/代码术语审计报告-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_* 标识符分布 + +**总量**:~314 处(270 处 .gd + 22 处 .tres + 22 处独立 `flag` 词) + +**核心逻辑文件(改动密度前 10)**: + +| 文件 | flag_ 命中 | 关键标识符 | +|---|---|---| +| smoke/smoke_all.gd | 105 | flag_place, flag_hit, flag_miss, flag_placed, _flag_consumed | +| core/settlement/grant_segment.gd | 23 | flag_hit, flag_miss, _flag_consumed, flag_settle | +| smoke/ui_input_probe.gd | 23 | flag_place, flag_cell | +| core/minesweeper_rules.gd | 18 | flag_place, has_flag, flag_range_free, _flag_miss_seen | +| core/battle_orchestrator.gd | 17 | flag_hit, flag_hit_premium, _flag_consumed | +| smoke/level_autoplay.gd | 16 | flag_placed, flag_hit, flag_miss | +| data/tables/feats.tres | 15 | "flag_hit"(on 触发), "echo_flags", "smith_flags", "flag_burst"(feat_id) | +| core/effect_engine.gd | 9 | `EVENTS` 含 "flag_hit"(:13)、"flag_missed"(:15);`MINE_EVENTS` 含 "flag_hit"、"flag_settle"(:20);天赋树合成行 `_push_trigger("tree", …, {"on": "flag_missed"})` 2 处(:149、:152);头注 :9 含「flag_missed 标错判定」 | +| presentation/views/battle_end_overlay.gd | 9 | flag_hit, flag_miss 统计显示 | +| presentation/views/board_view.gd | 7 | tex_flag, has_flag, flag_cell | + +**数据表字段(.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)` | + +**已知假阳性(显式排除,不改)**: + +| 文件 | 标识符 | 原因 | +|---|---|---| +| presentation/views/ui_assembler.gd | `size_flags_vertical` / `size_flags_horizontal` / `size_flags_stretch_ratio` | Godot 引擎 Control 内置属性 | +| core/config_db.gd | `_fatal_flag` | 无关变量(致命错误标记) | + +**存档影响面(Alpha 阶段可接受作废,不做迁移)**: + +| 持久化路径 | 涉及键 | 影响 | +|---|---|---| +| save.json → breakpoint.adventure_counters | `"echo_flags"`, `"smith_flags"` | 旧档计数器失效,Alpha 阶段可接受(2026-10-18 用户裁定) | + +### N2 · 中文禁用词分布(.gd 文件) + +| 禁用词 | 命中 | 主要落点 | +|---|---|---| +| 金币 | ~35 处 | UI 字符串(shop_overlay_view 5、camp_shop_presenter 3、battle_narrator 2、curio_pick_overlay 2、legend_overlay 1)+注释(smoke_all 10、battle_orchestrator 1 等) | +| 插旗 | ~100 处 | 注释为主(grant_segment 6、minesweeper_rules 4、board_view 4、smoke_all 14)+UI 字符串(hud_presenter 1、main.gd 1、legend_overlay 1) | +| 雷格 | ~80 处 | 注释(battle_orchestrator 11、smoke_all 31、minesweeper_rules 5、grant_segment 3、board_generator 1)+测试断言文本 | +| 惩罚格 | ~2 处 | treasure_items.gd 注释 | +| 旗(游戏概念) | ~15 处 | UI 字符串(legend_overlay "旗"、hud_presenter "已有旗")+注释("标中旗""标错旗""拔旗"等) | + +### 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**:工具脚本归文档批。 +- 🔴 **非游戏语境的 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-待办清单](../gdd/06-待办清单.md) | 「代码术语刷新批」条目状态推进为「已完成(迭代 31 卡①,合并 ``,2026-10-XX)」 | **反哺点**(`design/` 内,本批禁写):推进句写进 `reports/iter31-反哺点清单`,文档批落笔后本条清掉 | +| [术语表](../gdd/术语表.md) | flag→seal 重命名后,术语表「旗/控制」条目需同步改为「封印/控制」 | **反哺点**:文档批处理,本卡不改 design/ | +| [entities.yaml](../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-体验验证清单](../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"**;天赋树合成行 :149/:152 的 `{"on": "flag_missed"}` 同步改名;头注 :9 文本随批(处数不写死,以 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:注释「插旗」(3 处) +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 处) + +### 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**。 + +## 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/design/research/需求卡片-凭证件裁削批-2026-10-18.md b/design/research/需求卡片-凭证件裁削批-2026-10-18.md new file mode 100644 index 00000000..01c09aef --- /dev/null +++ b/design/research/需求卡片-凭证件裁削批-2026-10-18.md @@ -0,0 +1,216 @@ +# 需求卡片·凭证件裁削批(代码侧迁移) + +- **批次名**:凭证件裁削批(代码侧) +- **日期**: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,现 30 项,**无**豁免型)/`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**:`design/gdd/systems/冒险循环/奇物.md` v3.18 当前只存在于主区未提交改动与未合并分支 `curio-prune-20261018`(`HEAD:奇物.md` 无 v3.18),worktree 从 HEAD 检出读不到本卡事实源;同时 06「凭证件裁削批·代码侧迁移」状态列须由「待写卡」推进为「文档设计已闭合(奇物.md v3.18)+已写卡(本卡路径)+已编迭代 31」。两处均属 `design/` 落笔,**归用户/文档批,本批禁改**。 + +本卡不等冒记遗留两项(凭证归专长/资源=转换源判据句)的裁定——那两项不阻塞本卡。 diff --git a/roadmap.md b/roadmap.md index 4c88fe57..8f55aaf7 100644 --- a/roadmap.md +++ b/roadmap.md @@ -5,8 +5,8 @@ ## 当前位(只回答「现在该做什么」;三行内随批次换代,禁止在此扩写成状态快照) - **阶段**:M3——Alpha 版本的完整实现(2026-10-09 立规:未明令宣布完成前停留 M3,迭代只排 M3 需求,M4 不排期;根目录 stage.txt 为旧阶段开关仅存档)。 -- **迭代位**:迭代 1–30 全部已完成或已终止(末位=迭代 30 卡① 未开格类型徽章批,合并 `7ffd1dc0`,2026-10-17);**当前无在做的迭代**。 -- **下一步**:未编排。候选全在 06 状态列——营地交互重做五卡(已写卡待编迭代)、代码术语刷新批(待写卡)、迭代 30 原卡②③(待美术/设计定稿后重新立卡);编排与发令权归用户。 +- **迭代位**:迭代 1–30 全部已完成或已终止;**迭代 31 待开工**(两卡串行:卡①代码术语刷新批+卡②凭证件裁削批·代码侧,均 2026-10-18 编入)。 +- **下一步**:迭代 31 开工令(U0)归用户发。其余候选在 06 状态列——营地交互重做五卡(已写卡待编迭代)、迭代 30 原卡②③(待美术/设计定稿后重新立卡)。 ## 里程碑时间线 @@ -64,6 +64,7 @@ | 迭代 28 | 已完成(2026-10-15) | 已退役(git 历史可考) | 2026-10-15 | — | reports/iter28-实现报告-2026-10-15.md | | 迭代 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 周 | — | - 历史行的「—」= 该列事实不可考:迭代 1~8 早于需求卡片制;编排时点与预计周期不再回溯,细节查 git 提交史。 - 「已退役(git 历史可考)」= 需求卡片或实现报告曾存在,已按「证据只留最新」退役;已完成迭代的实现报告列只填 reports/ 现存路径或本保留字,不填「—」。 diff --git a/tools/pipeline_gate.py b/tools/pipeline_gate.py index 9388e2a6..559d8c1f 100644 --- a/tools/pipeline_gate.py +++ b/tools/pipeline_gate.py @@ -1,11 +1,13 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -r"""pipeline_gate.py — 工作流程流水线闸(06 条目状态机+roadmap 迭代总表+一次交叉核)。 +r"""pipeline_gate.py — 工作流程流水线闸(06 条目状态机+roadmap 迭代总表+需求卡片口径+一次交叉核)。 职责:机检 06 条目(标题元数据/属性齐备/状态词白名单/条件凭据/状态段累积制在场约束/特批/ 零命中)与 roadmap 迭代总表(六列/状态四形态/卡片与报告存在性/编入时间与预计周期的 历史行「—」豁免/周期≤2 周可特批豁免/单元格白名单/零命中);「已编迭代↔已写卡段↔迭代行 - 卡片列」交叉核只此一处。 + 卡片列」交叉核只此一处。2026-10-18 卡片冲突修订批补两条卡片机检:C1 关联文档同步面的 + 文档义务口径(生效 2026-10-17)、C2 设计事实源声明(生效 2026-10-18)——两条都按文件名 + 日期只追新规生效日之后的卡,旧卡属 git 历史留档不回头改。 约束:每红项一行「文件:行号 判据名 一句白话说明」,exit 0=全绿 / 1=有红 / 2=输入件缺失; 卡片与报告存在性相对 --repo-root 解析(缺省=本文件上两级);06 与 roadmap 均已为新格式 (2026-10-18 数据整改批),本闸已注册进 tools/run_all_gates.sh 文档域(08c 流水线闸)。 @@ -36,6 +38,16 @@ ART_DESIGN_WORDS = ("待美术设计", "美术设计中", "美术设计已闭合 ROADMAP_HEADER = ("迭代代号", "状态", "需求卡片", "编入时间", "预计周期", "实现报告") RESERVED_RETIRED = "已退役(git 历史可考)" +# ---- 卡片机检(2026-10-18 卡片冲突修订批补)---- +CARD_GLOB = "需求卡片-*.md" +CARD_DIR = "design/research" +SYNC_RULE_DATE = (2026, 10, 17) # req-card §6:实现批禁写 design/ 与根规则文件,义务一律列反哺点 +SOURCE_RULE_DATE = (2026, 10, 18) # req-card §2:设计事实源必填 +SOURCE_MARKS = ("设计事实源", "唯一事实源") # 两种合格写法,与库内既有卡片实际形态对齐 +SYNC_HEADING_RE = re.compile(r"^#{2,3}\s*\d*\.?\s*关联文档同步面") +BANNED_DOC_MARKS = ("design/", "../gdd/", "../registry/", "../research/", "../qa/", + "../dev/", "../ux/", "../art/", "roadmap.md", "CLAUDE.md") + DATE_RE = re.compile(r"\d{4}-\d{2}-\d{2}") VER_RE = re.compile(r"[vV]\d+(?:\.\d+)*") RESEARCH_RE = re.compile(r"design/research/[^\s()(),,]+") @@ -361,6 +373,60 @@ def cross_check(links, index, issues, where): "迭代 %d 行卡片列不含本条目已写卡路径 %s" % (no, card))) +def card_date(path): + """文件名尾日期 → (y, m, d) 元组;取不到返回 None(该卡跳过两条新规机检)。""" + found = DATE_RE.findall(path.stem) + if not found: + return None + return tuple(int(x) for x in found[-1].split("-")) + + +def check_cards(root, issues): + """C1 文档义务口径(生效 2026-10-17)+C2 设计事实源声明(生效 2026-10-18)。 + + 只检文件名日期达生效日的卡——更早的卡属已实现批次的历史留档,不回头改。 + C1 判据:「关联文档同步面」表内,目标格指向 design/ 或根规则文件、而义务格仍写 + 「随批」者红(2026-10-17 req-card §6 改口径后,这类点只能列 reports/ 反哺点清单)。 + C2 判据:全文既无「设计事实源」也无「唯一事实源」者红(两种写法都与库内实态对齐)。 + """ + dirn = root / CARD_DIR + if not dirn.is_dir(): + issues.append((str(dirn), 1, "零命中自检", "卡片目录不存在,C1/C2 无卡可检")) + return 0 + n = 0 + for path in sorted(dirn.glob(CARD_GLOB)): + when = card_date(path) + if when is None: + continue + n += 1 + text = path.read_text(encoding="utf-8-sig") + if when >= SOURCE_RULE_DATE and not any(mark in text for mark in SOURCE_MARKS): + issues.append((str(path), 1, "设计事实源缺失", + "须含「设计事实源」或「唯一事实源」声明句(req-card §2 三选一," + "GDD 节+版本号/样张+art-bible 版本/工程直入证据指认)")) + if when < SYNC_RULE_DATE: + continue + in_sec = False + for lineno, raw in enumerate(text.splitlines(), start=1): + stripped = raw.strip() + if SYNC_HEADING_RE.match(stripped): + in_sec = True + continue + if in_sec and stripped.startswith("#"): + in_sec = False + continue + if not in_sec or not stripped.startswith("|") or SEP_ROW_RE.match(stripped): + continue + cells = row_cells(stripped) + if len(cells) < 3 or cells[0] in ("文档", ""): + continue + if any(mark in cells[0] for mark in BANNED_DOC_MARKS) and "随批" in cells[2]: + issues.append((str(path), lineno, "文档义务口径", + "目标「%s」属实现批禁写面,义务却写「随批」——改标反哺点并列进 " + "reports/ 清单(req-card §6,2026-10-17 起)" % cells[0][:36])) + return n + + def main(): ap = argparse.ArgumentParser( description="工作流程流水线闸:06 条目状态机+roadmap 迭代总表+一次交叉核") @@ -382,13 +448,14 @@ def main(): links = check_todo(todo_text, issues, str(todo_path), root) index = check_roadmap(roadmap_text, issues, str(roadmap_path), root) cross_check(links, index, issues, str(todo_path)) + n_cards = check_cards(root, issues) for where, line, name, msg in issues: print("%s:%d %s %s" % (display(where, root), line, name, msg)) if issues: print("流水线闸 FAIL:红项 %d" % len(issues)) return 1 - print("流水线闸 PASS:06 条目 %d · 总表数据行 %d · 交叉核 %d 链全过" - % (len(parse_todo(todo_text)), len(index), len(links))) + print("流水线闸 PASS:06 条目 %d · 总表数据行 %d · 交叉核 %d 链 · 卡片口径 %d 张全过" + % (len(parse_todo(todo_text)), len(index), len(links), n_cards)) return 0