From 3be3f3e7c17094480fbfaed8f9dff3cdc5c3f9c2 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 3 Nov 2026 05:39:07 +0800 Subject: [PATCH 01/19] =?UTF-8?q?=E6=96=87=E6=A1=A3=E8=AE=BE=E8=AE=A1(?= =?UTF-8?q?=E6=9E=B6=E6=9E=84=E5=AE=A1=E6=9F=A55.1=E5=B0=81=E8=A3=85?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=C2=B7=E7=94=A8=E6=88=B7=E8=A3=81):=20?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E8=AE=A8=E8=AE=BA=E7=BB=93=E8=AE=BA=E8=90=BD?= =?UTF-8?q?=E6=A1=A3=E4=B8=A4=E4=BA=A4=E4=BB=98=E2=80=94=E2=80=94=E2=91=A0?= =?UTF-8?q?=E5=A4=84=E7=BD=AE=E8=AE=B0=E5=BD=95=20reports/=E5=A4=84?= =?UTF-8?q?=E7=BD=AE-=E6=9E=B6=E6=9E=84=E5=AE=A1=E6=9F=A55.1=E5=B0=81?= =?UTF-8?q?=E8=A3=85=E4=BF=AE=E5=A4=8D-2026-11-03.md(=E6=80=BB=E5=88=A4?= =?UTF-8?q?=E6=8D=AE=E5=85=AD=E6=9D=A1/=E6=A0=B9=E5=9B=A0=E5=AE=9A?= =?UTF-8?q?=E7=A8=BF=E4=B8=89=E6=97=A0=E5=8F=A0=E5=8A=A0/=E6=99=AE?= =?UTF-8?q?=E6=9F=A5=E4=BA=94=E5=A4=84=20core=20105=E8=A1=8C107=E5=A4=8419?= =?UTF-8?q?=E7=AC=A6=E5=8F=B7+presentation=20227=E8=A1=8C=E5=87=BA?= =?UTF-8?q?=E5=8D=A1/=E9=80=90=E9=A1=B9=E8=A3=81=E5=86=B3=E8=AE=B0?= =?UTF-8?q?=E5=BD=95/19=E7=AC=A6=E5=8F=B7=E8=A1=8C=E4=B8=BA=E5=BD=92?= =?UTF-8?q?=E5=B1=9E=E6=80=BB=E8=A1=A8/=E6=9E=B6=E6=9E=84=E9=94=9A?= =?UTF-8?q?=E7=82=B9;=20=E6=8E=A5=E6=94=B6=E6=96=B9=3D=E9=9C=80=E6=B1=82?= =?UTF-8?q?=E5=8D=A1=E7=89=87-=E6=9E=B6=E6=9E=84=E5=AE=A1=E6=9F=A55.1?= =?UTF-8?q?=E5=B0=81=E8=A3=85=E4=BF=AE=E5=A4=8D-2026-11-03.md+=E5=BE=85?= =?UTF-8?q?=E5=8A=9E=E6=B8=85=E5=8D=95=E6=9E=B6=E6=9E=84=E5=AE=A1=E6=9F=A5?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AE=A8=E8=AE=BA=E6=9D=A1=E7=9B=AE,=20?= =?UTF-8?q?=E5=8D=A1=E7=89=87=E6=88=90=E7=AB=8B=E5=8D=B3=E9=80=80=E5=BD=B9?= =?UTF-8?q?);=20=E2=91=A1code-conventions.md=20=E6=96=B0=E5=A2=9E=20=C2=A7?= =?UTF-8?q?1.6=20=E6=8B=86=E5=88=86=E4=BA=A4=E6=8E=A5=E4=B8=8E=E5=B0=81?= =?UTF-8?q?=E8=A3=85=E8=BE=B9=E7=95=8C(=E6=9D=A1=E4=B8=80=E6=8B=86?= =?UTF-8?q?=E5=88=86=E4=BA=A4=E6=8E=A5=E5=AE=9A=E4=B9=89=3D=E8=81=8C?= =?UTF-8?q?=E8=B4=A3=E8=BE=B9=E7=95=8C+=E4=BA=A4=E6=8E=A5=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=8F=8C=E9=BD=90=E5=A4=87=E6=89=8D=E7=AE=97=E6=8B=86?= =?UTF-8?q?=E5=88=86=E5=90=88=E6=A0=BC,=20=E5=85=88=E4=BE=8B=3DBoardInstal?= =?UTF-8?q?ler=20=E5=BC=95=E7=94=A8=E6=9D=9F=E6=B3=A8=E5=85=A5;=20?= =?UTF-8?q?=E6=9D=A1=E4=BA=8C=E5=B0=81=E8=A3=85=E8=BE=B9=E7=95=8C=3D?= =?UTF-8?q?=E8=B7=A8=E5=AF=B9=E8=B1=A1=E7=A6=81=E8=AE=BF=E9=97=AE=E4=B8=8B?= =?UTF-8?q?=E5=88=92=E7=BA=BF=E6=88=90=E5=91=98=E5=8F=AA=E8=B5=B0=E5=85=AC?= =?UTF-8?q?=E5=BC=80=E9=9D=A2)=E2=80=94=E2=80=94=E6=9C=AC=E6=89=B9?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=8E=E5=90=8E=E7=BB=AD=E9=97=B8=E4=BB=B6?= =?UTF-8?q?=E5=85=B1=E5=90=8C=E4=BE=9D=E6=8D=AE;=20GDD=20=E9=9B=B6?= =?UTF-8?q?=E6=94=B9=E5=8A=A8;=20=E6=96=87=E6=A1=A3=E5=9F=9F=E9=97=B8?= =?UTF-8?q?=E5=85=A8=E7=BB=BF(8=E9=97=B8=20all=5Fgreen)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/engineering/code-conventions.md | 6 ++ .../处置-架构审查5.1封装修复-2026-11-03.md | 93 +++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 reports/处置-架构审查5.1封装修复-2026-11-03.md diff --git a/design/engineering/code-conventions.md b/design/engineering/code-conventions.md index 7f7f07a9..1d3bafdc 100644 --- a/design/engineering/code-conventions.md +++ b/design/engineering/code-conventions.md @@ -34,6 +34,12 @@ ### 1.5 禁止事实约定 任何"大家默认这么做"的惯例必须成文进本文件(或 AGENTS.md)才算存在。写代码时发现未成文但必须遵守的约定 → 当场补条文,不许靠惯性延续。 +### 1.6 拆分交接与封装边界 +本节管拆分类改动的交接面与封装面,与 §1.1 拆分判据(职责轴)配合使用:§1.1 管怎么切,本节管切完之后件与件之间怎么往来。 + +1. **拆分交接定义**:拆出一个新类时,交付物必须同时写明职责边界与交接定义——新类构造时需要哪些依赖,由拆出它的类在构造它时一次交给它;新类需要回调拆出它的类的哪些方法,以 Callable 形式交付。两者齐备才算拆分合格。为什么:只切职责不定义交接,新件会伸手回原类内部拿东西,封装从拆件那天起就破了。正面先例=装板件的引用束注入(表数据、随机流、装板所需对象与出错回调一次性交付——架构文档「战斗编排域拆件定稿」节 BoardInstaller 行在册)。 +2. **封装边界**:任何代码不得访问其他对象的下划线成员;跨对象往来只走公开方法与属性。为什么:下划线只是命名约定,语言不设防、无编译期检查——此条是封装硬纪律,违者即红。 + --- ## 2. 契约纪律——跨层/跨类调用的语义 diff --git a/reports/处置-架构审查5.1封装修复-2026-11-03.md b/reports/处置-架构审查5.1封装修复-2026-11-03.md new file mode 100644 index 00000000..5e5f3b61 --- /dev/null +++ b/reports/处置-架构审查5.1封装修复-2026-11-03.md @@ -0,0 +1,93 @@ +# 处置:架构审查 5.1 封装修复批(2026-11-03) + +> **性质**:设计讨论段过程稿(裁决记录+取证事实)。**接收方**=reports/需求卡片-架构审查5.1封装修复-2026-11-03.md + 待办清单条目「架构审查优化讨论——全库架构审计读数的逐条裁决与整改分批」(2026-10-29 登记)。**寿命**:需求卡片成立即退役(吸收即死——结论吸收进卡片与 code-conventions,未决迁待办清单)。 +> **输入**:reports/审计-全库架构审查-2026-10-29.md §5.1(settlement 五段类直读写编排器私有成员;讨论段把普查扩到全库同模式面)+ 2026-11-03 讨论会话用户逐项裁决 + 2026-11-03 会话取证(19 符号逐个核过、行号为当日现址——行号写卡段复核)。 + +## 一、总判据(用户 2026-11-03 裁,本批一切设计遵循) + +1. **拆分判「错」的口径=交付物缺交接**:拆分的完整交付物是一个独立的类,须同时含职责边界与交接定义——构造时拿到什么、回调原类什么、只经公开面往来。五次拆件五次不合格。 +2. **修复=把五次拆件没做完的交接补完**:代码位置不动、职责归属零改动,只补构造交付与回调。 +3. **编排器保留面=architecture.md:141 登记原样**(战斗状态机与生命周期、行发射基建 _emit_row/_assert_row_source/_fatal、呈现投影、刷新面、nest_preview_count),本批零增零减。 +4. **法律先于修复**:code-conventions 两条增补先落(=§1.6 拆分交接定义+封装边界,本批交付二),两条是本批修复与后续闸件的共同依据。 +5. **GDD 零改动**(零行为变更的设计讨论,不触任何系统规则)。 +6. **范围**:core 五处进卡(编入需求卡片);presentation 层约 227 行出卡(不在本卡,冻结期内单开设计讨论——修法=视图补公开设置方法、装配代码改走设置方法);sim/probe/tests 出卡(测量面直构惯例+测试受控例外)。 + +## 二、根因(定稿陈述) + +拆件交付物只写了职责边界、没写交接定义——拆出的件没拿到它需要的东西,每次需要都变成伸手回原类内部。三层防护全部缺位,三无叠加: + +- 语言层:GDScript 无访问修饰符,下划线纯命名约定; +- 规约层:code-conventions 全文无跨对象访问条文(已核); +- 闸层:S1–S13 无此扫描。 + +局部每处合理(19 符号逐个核过全是正当需要),整体边界溶解:累计约 390 行、20+ 文件。 + +## 三、普查五处(core 层;2026-11-03 会话取证现址,行号写卡段复核) + +1. **settlement 七段→编排器**:105 行/107 处/19 符号(七段=五段段类+round_cycle+battle_refresh_flow)。分布=grant_segment 54/combat_segment 23/round_cycle 10/verdict_segment 9/battle_refresh_flow 5/aura_segment 2/decay_segment 2。构成=成员引用 72 处+编排器方法 35 处(逐符号与修后归属见五、总表)。 +2. **adventure_runner→BreakpointStore**:37 行直读写(_pending_next_level、_loadout_seeded、_resume_bp、_save_manager、_last_level_payload、_last_treasure_cleared、_bp_read)——adventure_runner.gd:37 注释自述「宿主读写经件」未落实。 +3. **save_manager→SlotStore**:9 行(slots._path 直读写 ×8+slots._migrate_legacy_save 私有方法调用;save_manager.gd:51/66/69/105/111/118-119/285-286)。 +4. **grant_segment→BattleFxHost**:6 行直写 _fx_new_resource_types(:82/:84)与 _fx_bonus_delta(:169-170/:378-379)。 +5. **config_db→三表容器**:3 行装配期写 _resolver(config_db.gd:157-159)。 + +presentation 层同模式约 227 行(抽样核实、未逐行判读)——出卡另议: + +| 文件 | 行数 | +|---|---| +| level_map_screen | 87 | +| main_ui_build | 70 | +| main_adventure_flow | 25 | +| standee_body | 16 | +| main_overlay_flow | 15 | +| main_debug_flow | 11 | +| main_esc_flow | 2 | +| board_view | 1 | + +## 四、逐项裁决记录 + +| 项 | 裁决 | +|---|---| +| 方向=补交接 | settlement 七段构造时收六个子对象引用(战斗事实 BattleFacts、单位容器 UnitContainer、伤害控制器 DamageController、奖励经济 RewardEconomy、状态容器 StatusContainer、效果宿主件 BattleFxHost)+七个编排器方法回调(_emit_row、_fatal、_install_and_reset、_battle_over、_exit_distribution、_emit_settlement_snapshot、_emit_composition_effects,以 Callable 交付)+段间引用(授予段引用直接交换——battle_refresh_flow 不再经编排器 _rounds 链式取授予段,改为直接持有授予段引用);编排器公开读数(round_index、db、action_economy、battle_result)一并改注入;段类对编排器引用归零。 | +| 搬家五方法 | _hero_atk→伤害域、_feat_yield_adjust→奖励域(奖励授予件)、_harmful_variants 与 _harmful_adjacent→地形棋盘域、_hits_of→伤害域。 | +| verdict 轮推进保留 | verdict 段经 _exit_distribution 触发轮推进保留现设计(架构在册七段结构,battle_orchestrator 段序骨架冻结——architecture.md:119)。 | +| battle_refresh_flow 同形 | battle_refresh_flow 同批同形改造(can_refresh/execute 两入口的 oc/self 入参一并改依赖交付)。 | +| 其余三处补公开面 | BreakpointStore 补公开读写方法;SlotStore 补路径公开读取口与迁移方法(或序列化职责归位,写卡定形态);BattleFxHost 补两个公开累积方法;表容器补 resolver 公开挂载方法。 | +| S13 成员数约束 | 段类新增依赖受 gdstyle 成员阈值约束,依赖可经束成员持有(先例=BoardInstaller 引用束注入——architecture.md:124「构造=引用束注入」)。 | +| 验证方式 | 同种子逐项比对(主证,手法先例=3.1+3.2 卡 battle_driver_drive_test 动作序列快照)+battle_settlement 套件全绿+五搬家方法各配真实入口断言+core 五处跨对象私取 grep 恒零(扫描面非空前置+零命中);对照表按「非行为改动+零行为变更证明」登记;禁变异类测试、禁撤销类取证。 | +| 排序 | 实现排队在 reports/需求卡片-架构审查3.1+3.2整改批-2026-11-02.md 之后(combat_segment 同文件避让——该卡甲案删 attack_segments 分支 :59-70)。 | +| 估时域 | 2–3 个工作日(写卡期精估)。 | + +## 五、19 符号行为归属总表(2026-11-03 会话取证) + +| 符号 | 处数 | 现在长在哪 | 修后归属 | 段类修后怎么拿到 | +|---|---|---|---|---| +| _facts | 24 | 编排器成员(BattleFacts 件引用,battle_orchestrator.gd:38) | BattleFacts 件(战斗事实域,架构在册) | 构造注入 BattleFacts 引用(六子对象之一) | +| _enemy_system | 22 | 编排器成员(UnitContainer 引用,battle_orchestrator.gd:48) | UnitContainer(B2 单位容器) | 构造注入 UnitContainer 引用 | +| _damage | 18 | 编排器成员(DamageController 引用,battle_orchestrator.gd:51) | DamageController(伤害单据管线) | 构造注入 DamageController 引用 | +| _reward_economy | 5 | 编排器成员(RewardEconomy 引用,battle_orchestrator.gd:50) | RewardEconomy(B4 奖励经济) | 构造注入 RewardEconomy 引用 | +| _status_effects | 2 | 编排器成员(StatusContainer 引用,battle_orchestrator.gd:49) | StatusContainer(B3 状态容器) | 构造注入 StatusContainer 引用 | +| _fx_host | 1 | 编排器成员(BattleFxHost 引用,battle_orchestrator.gd:52) | BattleFxHost(效果宿主件) | 构造注入 BattleFxHost 引用 | +| _rounds._grant_seg(链式) | 1 | battle_refresh_flow.gd:42 经编排器 _rounds 链式取授予段成员 | 段间引用——授予段引用直接交换 | 组装期直接交付授予段引用,不再穿编排器 | +| _emit_row | 16 | 编排器私有方法(行发射基建,架构在册保留面) | 留宿主(保留面登记原样,零增零减) | 构造注入 Callable(七回调之一) | +| _hits_of | 5 | 编排器私有方法 | 搬家→伤害域 | 经注入的 DamageController 公开方法直调 | +| _emit_composition_effects | 2 | 编排器私有方法 | 留宿主(保留面) | 构造注入 Callable | +| _battle_over | 2 | 编排器私有方法(battle_result 状态机写点域) | 留宿主(保留面) | 构造注入 Callable | +| _feat_yield_adjust | 2 | 编排器私有方法 | 搬家→奖励域(奖励授予件) | 经注入的奖励授予件公开方法直调 | +| _fatal | 1 | 编排器私有方法(行发射基建族) | 留宿主(保留面) | 构造注入 Callable | +| _hero_atk | 1 | 编排器私有方法 | 搬家→伤害域 | 经注入的 DamageController 公开方法直调 | +| _harmful_variants | 1 | 编排器私有方法 | 搬家→地形棋盘域 | 经注入的所属域件公开方法直调(具体形态写卡定) | +| _harmful_adjacent | 1 | 编排器私有方法 | 搬家→地形棋盘域 | 同上 | +| _install_and_reset | 1 | 编排器私有薄壳(装板复位,架构在册轴丙) | 留宿主(保留面) | 构造注入 Callable | +| _exit_distribution | 1 | 编排器私有方法(verdict 段经它触发轮推进) | 留宿主(现设计保留——七段结构冻结) | 构造注入 Callable | +| _emit_settlement_snapshot | 1 | 编排器私有方法(结算快照发射) | 留宿主(呈现投影出口不变) | 构造注入 Callable | +| **合计** | **107 处/105 行** | — | — | — | + +取证注意:成员七符号逐项加总 73、编排器方法十二符号逐项加总 34,与三、构成行记写的 72+35 有 ±1 出入(总处数 107 两路一致);行号与计数一律以写卡段复核为准。 + +## 六、架构锚点(architecture.md) + +- :119——B1 battle_orchestrator 职责列:段序骨架(七段结构冻结)、B2/B3/B4 唯一调用方=B1 域文件集。 +- :124——BoardInstaller 行:构造=引用束注入先例(装板薄壳+表数据、随机流、装板所需对象与出错回调一次性交付)。 +- :137——「战斗编排域拆件定稿」节头(拆件定稿全文入口)。 +- :139——轴甲两件:宿主保留面首登记与呈现投影「唯一出口不变」。 +- :141——轴丁两件:零豁免裁宿主保留面原文(总判据 3 的登记原样出处)。 From 057ccc672b9fd67d8f90e1629e93901274470a3c Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 3 Nov 2026 06:01:23 +0800 Subject: [PATCH 02/19] =?UTF-8?q?=E5=86=99=E5=8D=A1(=E6=9E=B6=E6=9E=84?= =?UTF-8?q?=E5=AE=A1=E6=9F=A55.1=E5=B0=81=E8=A3=85=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=89=B9):=20=E4=BA=94=E5=A4=84=E8=B7=A8=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E7=A7=81=E6=9C=89=E8=AE=BF=E9=97=AE=E4=BF=AE=E5=A4=8D=E9=9C=80?= =?UTF-8?q?=E6=B1=82=E5=8D=A1=E2=80=94=E2=80=94settlement=E4=B8=83?= =?UTF-8?q?=E6=AE=B5(105=E8=A1=8C/107=E5=A4=84/19=E7=AC=A6=E5=8F=B7?= =?UTF-8?q?=E7=A7=81=E5=8F=96)=E6=9D=9F=E4=BA=A4=E4=BB=98=E5=85=AD?= =?UTF-8?q?=E5=AD=90=E5=AF=B9=E8=B1=A1+=E4=B8=83=E5=9B=9E=E8=B0=83+?= =?UTF-8?q?=E6=AE=B5=E9=97=B4=E5=BC=95=E7=94=A8+=E5=85=AC=E5=BC=80?= =?UTF-8?q?=E8=AF=BB=E6=95=B0=E6=B3=A8=E5=85=A5=E5=AF=B9=E7=BC=96=E6=8E=92?= =?UTF-8?q?=E5=99=A8=E5=BC=95=E7=94=A8=E5=BD=92=E9=9B=B6/=E6=90=AC?= =?UTF-8?q?=E5=AE=B6=E4=BA=94=E6=96=B9=E6=B3=95=E5=90=84=E5=BD=92=E9=A2=86?= =?UTF-8?q?=E5=9F=9F=E5=AE=BF=E4=B8=BB(hero=5Fatk+hits=5Fof=E5=BD=92?= =?UTF-8?q?=E4=BC=A4=E5=AE=B3=E5=9F=9F/feat=5Fyield=5Fadjust=E5=BD=92?= =?UTF-8?q?=E5=A5=96=E5=8A=B1=E5=9F=9F/harmful=E4=B8=A4=E6=B3=95=E5=BD=92?= =?UTF-8?q?=E5=9C=B0=E5=BD=A2=E6=A3=8B=E7=9B=98=E5=9F=9F)/adventure=5Frunn?= =?UTF-8?q?er=E2=86=92BreakpointStore=E5=85=AC=E5=BC=80=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E9=9D=A237=E5=A4=84/save=5Fmanager=E2=86=92SlotStore=E5=85=AC?= =?UTF-8?q?=E5=BC=80=E8=AF=BB=E6=8A=95=E5=BD=B1+=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E5=85=AC=E5=BC=80=E5=8C=969=E8=A1=8C/grant=E2=86=92BattleFxHos?= =?UTF-8?q?t=E4=B8=A4=E5=85=AC=E5=BC=80=E7=B4=AF=E7=A7=AF=E6=96=B9?= =?UTF-8?q?=E6=B3=956=E8=A1=8C+config=5Fdb=E2=86=92=E4=B8=89=E8=A1=A8bind?= =?UTF-8?q?=5Fresolver=203=E8=A1=8C;=20=E9=9B=B6=E8=A1=8C=E4=B8=BA?= =?UTF-8?q?=E5=8F=98=E6=9B=B4=E6=89=B9(=E4=B8=BB=E8=AF=81=3D=E5=90=8C?= =?UTF-8?q?=E7=A7=8D=E5=AD=90=E9=80=90=E9=A1=B9golden=E5=AF=B9=E6=8B=8D+?= =?UTF-8?q?=E4=BA=94=E5=A4=84grep=E6=81=92=E9=9B=B6sweep=E5=B8=A6=E9=9D=9E?= =?UTF-8?q?=E7=A9=BA=E5=89=8D=E7=BD=AE=E6=AD=A3=E9=94=9A),=205=E5=BC=A0T?= =?UTF-8?q?=E5=8D=A1=E7=B2=BE=E7=A1=AE=E6=B1=87=E6=80=BB2.75=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=97=A5,=20=E5=AE=9E=E7=8E=B0=E6=8E=92=E9=98=9F?= =?UTF-8?q?=E5=9C=A83.1+3.2=E5=8D=A1=E5=90=8E(combat=5Fsegment=E5=90=8C?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E9=81=BF=E8=AE=A9);=20=E8=83=BD=E5=8A=9B?= =?UTF-8?q?=E6=B8=85=E5=8D=95=E9=9B=B6=E6=96=B0=E5=A2=9E=E8=A1=8C(?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E4=BE=9D=E6=8D=AE=E5=9C=A8=E5=8D=A1=E7=AC=AC?= =?UTF-8?q?8=E8=8A=82);=20=E6=9D=A1=E7=9B=AE5.1=E9=83=A8=E5=88=86=E6=8E=A8?= =?UTF-8?q?=E8=BF=9B=E5=B7=B2=E5=86=99=E5=8D=A1(=E5=AE=9E=E5=86=B5?= =?UTF-8?q?=E5=A2=9E=E8=A1=A5=E5=A4=84=E7=BD=AE=E8=AE=B0=E5=BD=95+?= =?UTF-8?q?=E6=9C=AC=E5=8D=A1=E4=B8=A4=E5=87=AD=E6=8D=AE=E8=B7=AF=E5=BE=84?= =?UTF-8?q?,=20=E5=85=B6=E4=BD=99=E9=83=A8=E5=88=86=E4=B8=8D=E5=8A=A8);=20?= =?UTF-8?q?pipeline=5Fgate=20PASS(30=E6=9D=A1=E7=9B=AE/50=E6=80=BB?= =?UTF-8?q?=E8=A1=A8=E8=A1=8C/=E4=BA=A4=E5=8F=89=E6=A0=B83=E9=93=BE/?= =?UTF-8?q?=E5=8D=A1=E7=89=876=E5=BC=A0=E5=85=A8=E8=BF=87)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...€求卡片-架构审查5.1封装修复批-2026-11-03.md | 288 ++++++++++++++++++ 待办清单.md | 2 + 2 files changed, 290 insertions(+) create mode 100644 reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md diff --git a/reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md b/reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md new file mode 100644 index 00000000..b8d3b88d --- /dev/null +++ b/reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md @@ -0,0 +1,288 @@ +# 需求卡片:架构审查 5.1 封装修复批(2026-11-03) + +来源:待办清单「架构审查优化讨论——全库架构审计读数的逐项裁决与整改分批(2026-10-29 登记,来源=审计发现)」条目 5.1 部分(**唯一事实源**:reports/处置-架构审查5.1封装修复-2026-11-03.md——处置记录与本卡并行成文,本卡开工时该件尚未落盘;T1 首步核其已落盘且与本卡第 3 节逐条一致,冲突即 L3 停卡。设计闭合凭据=2026-11-03 设计讨论会话裁决+审计报告 §5.1+architecture.md:119/:124/:137-146)。 +状态:已写卡(v1.0,2026-11-03 成文)。改动面:游戏代码(含随逻辑写/改的测试代码)。 + +## 1. 目标与完成定义 + +**这批做什么**:把 2026-11-03 设计讨论裁决的五处跨对象私有访问修复方案全部落码——封装收口、零行为变更: + +| # | 处置对象 | 现状 | 终态 | +|---|---|---|---| +| 1 | settlement 七段 → 编排器 | 七文件对编排器 `oc._` 私取 105 行/107 处/19 符号(本卡第 3 节 grep 实核) | 段类构造收引用束(六子对象+编排器公开协作件引用)+七个编排器方法回调(Callable 交付)+公开读数注入;段类对编排器引用归零 | +| 2 | 编排器五个放错位置的方法 | `_hero_atk`/`_feat_yield_adjust`/`_harmful_variants`/`_harmful_adjacent`/`_hits_of` 留宿主、段类经宿主引用直调(architecture.md:145「现状形态」) | 各归领域宿主(伤害域/奖励域/地形棋盘域),宿主原方法删除禁留壳 | +| 3 | adventure_runner → BreakpointStore | `_bp_store._` 直读写 37 处(32 行;adventure_runner.gd:37 注释自述「宿主读写经件」未落实) | BreakpointStore 公开方法面承接,宿主私取清零 | +| 4 | save_manager → SlotStore | `slots._path` ×8+`slots._migrate_legacy_save` 私有方法调用 ×1(save_manager.gd:51/66/69/105/111/118-119/285-286) | SlotStore 公开读投影 `active_path()`+迁移方法公开化承接 | +| 5 | grant_segment → BattleFxHost;config_db → 三表容器 | grant 直写 `fx_host._fx_new_resource_types`(:82/:84)与 `fx_host._fx_bonus_delta`(:169-170/:378-379)共 6 行;config_db.gd:157-159 三行装配直写三表 `_resolver` | BattleFxHost 两个公开累积方法;三表 schema 各加公开挂载方法 `bind_resolver` | + +**什么状态算完**:五处的每一条改动都落码、都有第 8 节对照表配对的验收断言在当轮真实跑批中通过;主证=同种子逐项比对(改前改后动作序列快照逐位同,T1 固化、全程保持绿)+battle_settlement 套件全绿;结构性证据=core 五处跨对象私取 grep 恒零(扫描面非空前置+零命中);代码域闸全绿(冒烟+单元+探针+渲染/静态);两份 reports/ 产出物(实现报告+反哺点清单)写齐。 + +**排序义务**:本卡实现排队在 reports/需求卡片-架构审查3.1+3.2整改批-2026-11-02.md 之后(已编迭代 50,未开工)——combat_segment.gd 同文件避让(该卡甲案删 attack_segments 分支 :59-70,本卡第 3 节 combat 行号在其合回后漂移,T1 复核以 grep 符号锚定位)。 + +## 2. 设计事实源 + +- **处置记录(输入合同,逐条一致)**:`reports/处置-架构审查5.1封装修复-2026-11-03.md`——五处裁决方案、段类终态、出卡边界。本卡第 3 节现状实查与第 4/7 节签名设计是其机械承载;T1 复核两件一致(冲突=上游缺陷,L3 停卡)。 +- **审计背景**:`reports/审计-全库架构审查-2026-10-29.md` §5.1(settlement 五段类直读写编排器私有成员 20+ 处;行号已漂移,以本卡第 3 节实查为准)。 +- **架构登记**:`design/engineering/architecture/architecture.md`——:119(battle_orchestrator 保留面与 B1 域文件集)、:124(BoardInstaller 引用束注入先例——「构造=引用束注入(……防 _init max-parameters 新键)」)、:137-146(战斗编排域拆件定稿::140 轴丙、:141 编排器保留面登记、:143 跨件单向接线、:145 段类随动现状句)。 + +## 3. 现状事实(2026-11-03 worktree arch51-card 实查,基点 6261b36e;开工自行复核) + +### 3.1 五处私取面盘点 + +**处 1·settlement 七段 → 编排器**(game/core/settlement/):`grep -c 'oc\._'` 逐文件=grant_segment 54/combat_segment 23/round_cycle 10/verdict_segment 9/battle_refresh_flow 5/aura_segment 2/decay_segment 2,合计 **105 行**;`grep -o "oc\._[a-z_]*" | wc -l`=**107 处**(grant:131 与 grant:424 两行各含 2 处);符号 19 种=`_facts`×24、`_enemy_system`×22、`_damage`×18、`_emit_row`×16、`_reward_economy`×5、`_hits_of`×5、`_status_effects`×2、`_feat_yield_adjust`×2、`_emit_composition_effects`×2、`_battle_over`×2、`_rounds`×1(:42 `oc._rounds._grant_seg` 跨两层)、`_install_and_reset`×1、`_hero_atk`×1、`_harmful_variants`×1、`_harmful_adjacent`×1、`_fx_host`×1、`_fatal`×1、`_exit_distribution`×1、`_emit_settlement_snapshot`×1。另有对编排器**公开**成员访问:action_economy×11、db×7、minesweeper×6、round_index×3、fx_host()×3、battle_result×2、rng×2、attune_param_sum()×1(grant:280)、perfect_sweep_earned()×1(grant:284)。 + +**处 2·搬家五方法**(均在 battle_orchestrator.gd,仅段类与编排器自用): + +| 方法 | 现址 | 调用面 | +|---|---|---| +| `_hero_atk() -> int` | battle_orchestrator.gd:70-71(读 `_facts.encounter` hero_atk 键、缺省 db.combat.hero.atk——E4 派生读,禁快照成员) | combat_segment:55;编排器 spawn 消费点 :282;测试 roll_multiplier_test.gd:45-59 经真实链路覆盖(零直调) | +| `_feat_yield_adjust(snap, positive, pos_m, neg_m)` | :452-461(读 `_reward_economy.polarity_row`) | grant_segment:99/:140 | +| `_harmful_variants(vids)` | :466-473(读 db.combat.variation) | grant_segment:87;_harmful_adjacent 内部 :484 | +| `_harmful_adjacent(cell)` | :478-485(读 minesweeper.current_board) | grant_segment:339 | +| `_hits_of(hits, kind)` | :489-494(纯过滤) | grant_segment:110/:115/:138/:356、combat_segment:62(该行随 3.1+3.2 批甲案删除)、测试 adventure_feats_test.gd:671/:691/:727 | + +**处 3·adventure_runner → BreakpointStore**:`grep -o "_bp_store\._[a-z_]*" | wc -l`=**37 处**(32 行)=`_resume_bp`×8、`_pending_next_level`×7、`_save_manager`×6、`_bp_read`×5、`_loadout_seeded`×5、`_last_level_payload`×4、`_last_treasure_cleared`×2。分布:adventure_runner.gd:107/:115/:157/:168/:180/:185/:189/:191/:201/:220/:235/:241/:300-302/:325-326/:376-378/:388/:412/:421/:430/:438/:456/:464/:467-468/:474-476。BreakpointStore(breakpoint_store.gd)类变量 15(:48-63——**贴顶禁再增**,architecture.md:113 同款登记);公开方法现 5(snapshot/restore_ledger/restore_curio_state/apply_resume_params/restore_stop_bank_fragments);`_bp_read`(:196-202)内部消费点 :160。测试面:feat_vouchers_test.gd 与 meta_progression_forge_test.gd 等 12 处 `orch._rounds._grant_seg._judge_seal(...)` 直调与 `orch._rounds.mines_hits` 7 处——`_grant_seg`/`mines_hits` 成员名与归属不变,零波及。 + +**处 4·save_manager → SlotStore**:save_manager.gd:51(`slots._migrate_legacy_save(LEGACY_SAVE_PATH, slots.slot_path(1), ...)`)+:66/:69/:105/:111/:118/:119/:285/:286(`slots._path` ×8)。SlotStore(slot_store.gd)`_path` :9;`_migrate_legacy_save` :150-163(唯一外部调用方=save_manager:51;件内零调用);公开读投影先例=`has_write_target()` :53-54(`_path != ""`)。SlotStore 类变量 4、公开方法 10。 + +**处 5·grant_segment → BattleFxHost+config_db → 三表容器**:grant_segment.gd:82-84(`fx_host._fx_new_resource_types.has(ctype)` 读+`[ctype] = true` 写——空串短路边界在 :82)与 :169-170、:378-379(`fx_host._fx_bonus_delta.has(axis)` 守卫+`[axis] += delta`)。BattleFxHost 类变量 15(battle_fx_host.gd:23-37——**贴顶禁再增**,头注 :10-16 自封)、公开方法 16、两私 members 无成员外读者(grep 全库仅 grant 四处)。config_db.gd:157-159 三行 `combat.board_gen._resolver = _resolver`/`combat.enemy._resolver = _resolver`/`run.difficulty._resolver = _resolver`;三表 `_resolver` 声明=board_gen_table.gd:113、enemy_table.gd:212、difficulty_table.gd:33(均无类型注解;消费点 :118/:217/:38)。表实例经 `load()` 出 .tres、无法带构造参,装配期注入是唯一时点(config_db.gd:131-159 `_assign_loaded`)。 + +### 3.2 写 T 卡依据的其他现状 + +- **段类现状形态**:五段构造=grant/combat 三参(host/fx_host_ref/reward_grant_ref)、aura/decay/verdict 单参(host);RoundCycle 三参直构(host/fx_host_ref/reward_grant_ref,round_cycle.gd:22-29);battle_refresh_flow 全 static(can_refresh/execute 收 `oc` 入参,:15-43)。编排器 `_init`(battle_orchestrator.gd:211-237)建件序=facts(218)→reward_economy(219)→damage(221)→fx_host(223)→reward_grant(225)→RoundCycle(237);类变量 15(38→15 后贴顶)。 +- **编排器回调宿主方法现签名**:`_emit_row(head, ri, display, value, extra)` :750;`_fatal(msg)` :791;`_install_and_reset(during_round := false) -> bool` :392;`_battle_over(result)` :610;`_exit_distribution()` :575(内含 :593 `_rounds.roll_round_actions()`);`_emit_settlement_snapshot(verdict)` :534;`_emit_composition_effects(side, ri)` :524;公开读投影先例=`_attune_safe_seen_read` :139(RewardGrant attune_safe_seen_cb)、`_pool_effective` :513(pool_effective_cb)——**读投影 Callable 交付是既有形态**(architecture.md:121)。 +- **编排器三调用点**:`can_refresh()`/`player_request_refresh()` 单行转发(:598-607);`_on_round_end` → `_rounds.settle_if_due()`(:445-447);begin_battle → `_rounds.roll_round_actions()`(:262)。facade 公开签名零参(presentation 路径)。 +- **测试连带面**:settle_segments_test.gd:20-24 五段 `new(oc, ...)` 直构断言、:28-34 宿主回指断言(`oc._rounds._grant_seg.oc == oc` 等 6 条)——随束形态换代改写;adventure_feats_test.gd:671/:691/:727 `orch._hits_of` 直调——随搬家改指。其余 orch._ 访问(`_facts`×6、`_rounds`×13、`_emit_row`×2)所涉宿主成员全保留,零波及。round_flow_skill_pool_test/seal_polarity_test/refresh_feats_test/effect_port_test 等走公开入口,零改写。 +- **gdstyle 基线**:tools/gdstyle_baseline.txt 仅 5 键(adventure_runner 类变量 23、level_runner 两键、board_view 两键)——本卡触件均无登记值,T1 现场读数即对账基线。S13 默认阈值:公开方法 ≤20/类变量 ≤15/单函数分支 ≤8/返回 ≤6。 +- **静态闸**:S7_B1_SET 与 S8_FILES(game/tests/static_scan.sh:317/:361)已含七段文件——本批零闸件改动。S9 R1A 判据=`var x: Dictionary|Array` 裸注解(tools/audit_type_hints.py:22)——新增成员一律具体类名或参数化泛型。 +- **能力清单**:game/tests/README.md 在役(本卡判据引用行=:59/:63/:86/:89/:92/:124/:174,能力名见第 8 节对照表)。 + +## 4. 设计契约(违反即返工红线) + +- 🔴 **逐条一致**:本卡一切内容与处置记录逐条一致;实现段发现卡面与处置记录冲突=上游缺陷,停卡退回写卡段(L3)。 +- 🔴 **零行为变更**:同种子同输入下动作序列、明细行流、结算快照、信号顺序逐位一致(T1 golden 主证全程保持绿);RNG 消费序零漂移(behavior_roll/encounter/fx_reveal/gp_drop 四封闭流的流名、开流时点、取号序逐字);明细行协议词表零触碰。 +- 🔴 **段类对编排器引用归零**:七个 settlement 文件(grant/combat/round_cycle/verdict/battle_refresh_flow/aura/decay)全文 `\boc\b` 标识符零命中(含头注与行内注释——随改写一并清除)。 +- 🔴 **编排器保留面零增减**:architecture.md:141 登记原样——战斗状态机与生命周期、行发射基建(_emit_row/_assert_row_source/_fatal)、呈现投影、刷新面、nest_preview_count。七回调的宿主方法体零改动(Callback 交付不搬家:_emit_row/_fatal/_install_and_reset/_battle_over/_exit_distribution/_emit_settlement_snapshot/_emit_composition_effects 全部留宿主)。 +- 🔴 **搬家五方法禁留壳**:宿主原方法删除,禁兼容别名、禁转发壳、禁注释化残段(第 13 节全款适用)。 +- 🔴 **束形态(引用束注入,BoardInstaller 先例 architecture.md:124)**: + - **编排器束**(`_init` 组装一个 `Dictionary`,封闭 20 键):`facts`/`units`/`damage`/`status_effects`/`reward_economy`/`reward_grant`/`fx_host`/`minesweeper`/`db`/`action_economy`/`rng` + `emit_row_cb`/`fatal_cb`/`install_cb`/`battle_over_cb`/`exit_distribution_cb`/`emit_snapshot_cb`/`emit_composition_cb` + `attune_param_sum_cb`/`perfect_sweep_cb`。前 11 键=六子对象(BattleFacts/UnitContainer/DamageController/RewardEconomy/StatusContainer/BattleFxHost)+四个既有公开协作件引用(minesweeper/rng/reward_grant——段类现役消费面所需)+两公开读数引用(db/action_economy);后 9 键=七个编排器方法回调(Callable 绑宿主对应方法)+两个公开读投影回调(`attune_param_sum(kind) -> int`/`perfect_sweep_earned() -> bool`——RewardGrant attune_safe_seen_cb/pool_effective_cb 同款先例)。 + - **接收方各取所需**:RoundCycle 收全束并分发五段(各段构造收同一束);RoundCycle 解包自用七键(facts/units/fx_host/db/action_economy/rng/emit_row_cb);各段断言各自必需键在束(BattleFxHost :41-42 assert 缺键先例)。必需键分配=grant 12(facts/units/damage/reward_economy/fx_host/minesweeper/db/action_economy/reward_grant/emit_row_cb/attune_param_sum_cb/perfect_sweep_cb)、combat 10(facts/units/damage/status_effects/fx_host/minesweeper/db/emit_row_cb/fatal_cb/reward_grant)、aura 1(emit_composition_cb)、decay 2(status_effects/emit_row_cb)、verdict 5(units/emit_row_cb/emit_snapshot_cb/battle_over_cb/exit_distribution_cb)。 + - **换图刷新流程件同批同形**:BattleRefreshFlow 由 static(oc 入参)改实例——`_init(bundle: Dictionary)` 收 8 键(facts/db/action_economy/fx_host/reward_economy/minesweeper/install_cb/grant_seg);can_refresh/execute 两入口的 `oc` 入参改依赖交付,编排器两公开方法单行转发形态不变(architecture.md:123)。grant_seg 键=段间引用(RoundCycle 构造五段后写入副本束再建本件——授予段引用直接交换图流程件,`oc._rounds._grant_seg` 跨两层私取随之消灭)。 + - **公开读数注入**:db/action_economy=引用注入(构造期稳定);round_index/battle_result=**调用参数现值交付**(两标量每拍变值,构造期值注入必陈旧)——`settle_if_due(battle_result: String, ri: int)`、`roll_round_actions(ri: int)`、`can_refresh(battle_result: String)`、`execute(battle_result: String, round_index: int)`,编排器调用点传现值(:262/:447/:593/:598-607 四处),facade 零参签名不变。 +- 🔴 **跨件单向接线**:段类↔编排器只经束注入(引用+Callable),禁双向强引用;注入 Callable 亦属接线面、禁为省参数改持对象引用(architecture.md:143 同款;段类/编排器均 RefCounted,环引用随每战新建泄漏)。 +- 🔴 **读投影消费形态**:Callable.call 返回 Variant,消费一律 `int(...)`/`bool(...)` 包裹(battle_fx_host.gd:128 facts_cb.call 消费先例)。 +- 🔴 **S9 参数化形态**:本批全部新增成员声明与函数注解——具体类名(`var facts: BattleFacts`)或参数化泛型(`Dictionary[Variant, Variant]`);裸 `Dictionary`/`Array` var 注解=S9 R1A 红。迁移函数(五方法)注解逐字保持原形(原签名已过 S9)。 +- 🔴 **fail-fast**:束缺键 assert 致命;零软回退。Core 零 UI 依赖不破(全套件 `--headless --script` 可跑通)。 +- 🔴 **测试纪律**:禁变异类测试、禁撤销类取证;禁删断言/放宽阈值换绿(第 8 节申报清单之外零删改)。 + +## 5. 范围边界 + +**收件**=第 1 节表五行全部(settlement 七段解耦+搬家五方法+breakpoint_store 公开面+slot_store 公开面+battle_fx_host 两累积方法+三 schema 挂载方法,及各自的调用点改址与测试适配)。 + +**不收件**(去向已指认): +- presentation 层约 227 行私取面——**另开设计讨论**(本卡裁决范围外;去向=待办清单本条目实况,非本批)。 +- sim/probe/tests 的测量面直构惯例与测试受控例外——零清扫(orch._facts/orch._rounds/orch._emit_row 等测试直连维持现状)。 +- 段类→协作件残余私取一处:grant_segment.gd:197 `oc._damage._emit_hero_damage_taken(...)` 随本批改经 `damage.emit_hero_damage_taken(...)`(DamageController 该方法去下划线公开化,见 T2)——除此之外段类对 damage/fx_host/reward_grant 公开成员的直读(counters_ctx/engine/facts_inject/defer)零触碰。 +- 职责归属零改动(除搬家五方法——已裁的五处归位);编排器七回调宿主方法体零改动;架构七段结构零改动(五段段序、SettlementTable.segment_order、RoundCycle/BattleRefreshFlow/五段段类的文件与职责登记全部在案不动)。 +- 闸件(static_scan.sh)零改动;MC/模拟零跑(无数值改动);`tools/gdstyle_baseline.txt` 零改动(本批无键恶化,见第 14 节)。 + +## 6. 关联文档同步面 + +实现批禁写 `design/` 整个目录、两份根流程清单与 `game/tests/README.md`;下表每条的落文义务全部进 `reports/iter-反哺点-<日期>.md`(N=编排段定),由用户裁决后归文档批落文: + +| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务(反哺点清单逐条承载) | +|---|---|---| +| design/engineering/architecture/architecture.md | :125 RoundCycle 行「三参直构(host/fx_host_ref/reward_grant_ref——五段构造透传不落成员)」→ 束注入+持有 BattleRefreshFlow+公开方法 3→4+类变量 8→15(贴顶);:123 BattleRefreshFlow 行 static 两入口收 oc → 实例束注入、宿主改经 RoundCycle 交接 grant_seg、类变量 0→8;:127 settlement/ 五段段类行构造形态句 → 束注入、对编排器零引用;:122 damage_controller 行实测类变量 12→13+公开面净增(hero_atk/hits_of/emit_hero_damage_taken);:121 RewardGrant 行 +feat_yield_adjust;:120 BattleFxHost 行 +两累积方法(类变量 15 不变);核心层表 A2 minesweeper_rules 行公开面 18→20(贴顶);核心层表 breakpoint_store 行公开方法面 5→18 | 反哺点清单逐条列行号与改后登记内容——**机械面文档禁直改** | +| design/gdd/systems/战斗循环/战斗结算.md | 无陈述变化(明细流水词表、五段段序、段边界全部零触碰——零行为变更批) | 反哺点清单写「零反哺」确认行 | +| 术语表 | 无新术语(引用束注入/读投影/公开方法面均仓库现行词) | 确认行「零新增术语」 | + +(机检口径:本表同步义务格无一条写「随批」。) + +## 7. 任务卡 T1..T5 + +### 卡前·文件结构图 + +全部行为面=非行为改动(零行为变更批),行标【非行为】+对照表 R 行号;测试件全部为随逻辑写/改的测试代码。一起改的按职责放一起——段类七文件同卡(T2)、存档断点两对同卡(T3)。 + +``` +core 层(编排域) + game/core/battle_orchestrator.gd 【非行为 R1/R2】_init 束组装(20 键);:70-71/:452-461/:466-473/:478-485/:489-494 五方法删除;:282 hero_atk 改指 _damage.hero_atk();:262/:447/:593 三调用点传参;:598-607 facade 改经 _rounds.refresh_flow() + game/core/settlement/round_cycle.gd 【非行为 R1】束注入(15 成员贴顶)+持有/构建 BattleRefreshFlow+settle_if_due/roll_round_actions 签名扩展+refresh_flow() 读出口 + game/core/settlement/grant_segment.gd 【非行为 R1/R2/R3】束解包 12 成员+54 处改址+:82-84/:169-170/:378-379 改公开累积方法+头注改写 + game/core/settlement/combat_segment.gd 【非行为 R1/R2】束解包 10 成员+23 处改址+hero_atk 改指 + game/core/settlement/aura_segment.gd 【非行为 R1】单回调成员+头注改写 + game/core/settlement/decay_segment.gd 【非行为 R1】两成员+改址 + game/core/settlement/verdict_segment.gd 【非行为 R1】束解包 5 成员+四回调改址 + game/core/settlement/battle_refresh_flow.gd 【非行为 R1】static 改实例+束注入 8 成员+grant_seg 段间引用 + game/core/damage_controller.gd 【非行为 R2】+facts 成员(12→13)+hero_atk()+static hits_of()+_emit_hero_damage_taken 公开化(:449/:561 内部调用点随改) + game/core/reward_grant.gd 【非行为 R2】+feat_yield_adjust() + game/core/minesweeper_rules.gd 【非行为 R2】+harmful_variants()/harmful_adjacent()(公开 18→20 贴顶) + game/core/battle_fx_host.gd 【非行为 R3】+mark_new_resource_type()/+add_bonus_delta()(成员 15 不变) +core 层(冒险/存档域) + game/core/breakpoint_store.gd 【非行为 R4】+13 公开读写方法面(成员 15 不变;_bp_read 更名 bp_read 公开化——:160 内部调用点随改) + game/core/adventure_runner.gd 【非行为 R4】37 处改址(:107..:476 逐处) + game/core/save_manager.gd 【非行为 R5】:51/:66/:69/:105/:111/:118-119/:285-286 九行改址 + game/core/slot_store.gd 【非行为 R5】+active_path();_migrate_legacy_save 更名 migrate_legacy_save 公开化 + game/core/config_db.gd 【非行为 R6】:157-159 三行改经 bind_resolver() + game/data/schemas/board_gen_table.gd 【非行为 R6】+bind_resolver(resolver: ConfigDbResolver) + game/data/schemas/enemy_table.gd 【非行为 R6】同上 + game/data/schemas/difficulty_table.gd 【非行为 R6】同上 +测试件(随逻辑写/改) + tests/unit/battle_settlement/settlement_wiring_snapshot_test.gd 【非行为 R1·新增】同种子逐项 golden 对拍(主证) + tests/unit/core/encapsulation_sweep_test.gd 【非行为 R1–R6·新增】五处结构性零命中扫描(非空前置+正锚) + tests/unit/core/settle_segments_test.gd 【非行为 R1】:20-34 束构造与同一性断言适配 + tests/unit/core/adventure_feats_test.gd 【非行为 R2】:671/:691/:727 hits_of 改指 DamageController.hits_of + tests/run_all.gd 【非行为】manifest +2 行(snapshot/sweep) +文档件 + game/tests/README.md 写卡段判断=零编辑(第 8 节能力行判断依据)——实现批禁写,批末只核对表上能力名与对照表引用一致 +``` + +--- + +**T1 基线固化与主证落盘**(估时 0.25 工作日;区间 0.25–0.5) +取用:无(本卡起点)。产出:golden 基线(改前读数冻结)+S13 对账基线+grep 底账;本卡实现排序核对。 + +- [ ] 核对实现排序在案:3.1+3.2 卡(迭代 50)未合回则本批不开工(第 1 节排序义务);combat_segment.gd 现址复核(甲案 :59-70 分支已删则以 grep 符号锚定位,行号漂移即记录进实现报告,禁改判据) +- [ ] 核对处置记录 `reports/处置-架构审查5.1封装修复-2026-11-03.md` 已落盘且与本卡第 3 节逐条一致(冲突=L3 停卡) +- [ ] 新增 tests/unit/battle_settlement/settlement_wiring_snapshot_test.gd(extends SceneTree+Kit.check 主通道,全类型标注):手搭驱动=`ConfigDbScript.new()`+`load_tables("res://data/tables", true)`→`RngServiceCore` set_master_seed(4242)→`BattleOrchestrator.new(db, rng)`;捕获面=`step_row` 全量行数组+`settlement_snapshot` 全量载荷数组+`battle_finished` 载荷+收束时 `presentation_snapshot()` 关键键(round/battle_result/hero.hp/enemies.size())。驱动序(逐字定死):①`begin_battle({"level_index": 1, "node_depth": 1, "hero_hp": int(db.combat.hero.max_hp), "voucher_rap": 20})`;②轮 1:`AutoPlayer.choose_dig(minesweeper)` 返 `{dig_cell, hero_cell}` 非空则 `settle_batch([{"action": "move", "cell": hero_cell}])`→`settle_batch([{"action": "dig", "cell": dig_cell}])`→对首个已揭示安全格 `settle_batch([{"action": "seal_place", "cell": c}])`→`settle_batch([{"action": "stop"}])`;③轮 1 结算后 `player_request_refresh()`(voucher_rap=20 保证 RAP 抵折后价——覆盖换图刷新链:can_refresh/execute/install_cb/grant_seg 成功事实);④轮 2:choose_dig 一挖一停;⑤轮 3:径直 `settle_batch([{"action": "stop"}])`。断言=捕获序列与 `const GOLDEN`(行字典逐位含 type/source_class/origin_cell/round_index/display_name/value/其余载荷键)逐位相等〔封装5.1 V1〕 +- [ ] **改前取数**:本步骤在任何生产码改动之前执行——先写测试与空跑转储通道(GOLDEN 为空时打印捕获序列 JSON 后按预期码退出),在未改树上跑出 golden、填入 GOLDEN 常量、复跑全绿;golden 即改前基线读数(不构成验收,验收=改后全程保持绿) +- [ ] S13 对账基线:对本卡全部 core/data 存量触件(第 14 节清单 15 件)现场跑 gdstyle 记读数为基线(既有登记仅 adventure_runner 类变量 23 一件照登对账);跑 `python tools/run_smoke.py` 冒烟基线全绿读数落实现报告 +- [ ] grep 底账四件落实现报告:`oc\._`(settlement 七文件)、`_bp_store\._`(adventure_runner)、`slots\._`(save_manager)、`_fx_new_resource_types|_fx_bonus_delta`(grant)与 `\._resolver =`(config_db)——命中行号清单=T5 sweep 的改前底账 + +**T2 settlement 七段解耦+搬家五方法**(估时 1.25 工作日;区间 1–1.5) +取用:T1 golden 基线。产出:处 1+处 2 清零——段类对编排器引用归零、五方法归位。 + +- [ ] battle_orchestrator.gd `_init`(:211-237):RoundCycle 构造改 `RoundCycle.new(束)`——束 20 键逐字(第 4 节束形态表;Callable 键绑自对应方法:`"emit_row_cb": _emit_row`、`"fatal_cb": _fatal`、`"install_cb": _install_and_reset`、`"battle_over_cb": _battle_over`、`"exit_distribution_cb": _exit_distribution`、`"emit_snapshot_cb": _emit_settlement_snapshot`、`"emit_composition_cb": _emit_composition_effects`、`"attune_param_sum_cb": attune_param_sum`、`"perfect_sweep_cb": perfect_sweep_earned`) +- [ ] 搬家五方法落位(宿主体逐字迁移、注解逐字保持): + - damage_controller.gd:`_init` 加第五参 `facts_ref`(成员 `var facts: BattleFacts`,:49 构造体加行);新增 `func hero_atk() -> int`(体=battle_orchestrator.gd:70-71 逐字,`_facts`→`facts`);新增 `static func hits_of(hits: Array, kind: String) -> Array`(体=:489-494 逐字);`_emit_hero_damage_taken` 更名 `emit_hero_damage_taken` 公开化(体逐字;内部调用点 :449/:561 随改) + - reward_grant.gd:新增 `func feat_yield_adjust(snap: Dictionary, positive: bool, pos_m: int, neg_m: int) -> Dictionary`(体=:452-461 逐字——reward_economy 为本件既有成员 :22) + - minesweeper_rules.gd:新增 `func harmful_variants(vids: Array) -> Array` 与 `func harmful_adjacent(cell: Vector2i) -> Array`(体=:466-473/:478-485 逐字——db 为本件构造参、current_board() 自有) + - battle_orchestrator.gd:五方法整段删除(:70-71/:452-461/:466-473/:478-485/:489-494);:282 `hero_atk_override: _hero_atk()` → `_damage.hero_atk()` +- [ ] round_cycle.gd 重写:`_init(bundle: Dictionary)`——断言 7 必需键(facts/units/fx_host/db/action_economy/rng/emit_row_cb)后解包为同名成员;五段构造改 `XxxSegment.new(bundle)`;复制束写入 `"grant_seg": _grant_seg` 后构建 `BattleRefreshFlow.new(束副本)`;`settle_if_due(battle_result: String, ri: int)`(:35→参数、:40 删、段驱动用 ri);`roll_round_actions(ri: int)`(:67/:80 用 ri);新增 `func refresh_flow() -> BattleRefreshFlow`;全文 `oc.` 改址(映射表=`oc._facts`→`facts`、`oc._enemy_system`→`units`、`oc._emit_row`→`emit_row_cb.call`、`oc._fx_host`→`fx_host`、`oc.db`→`db`、`oc.action_economy`→`action_economy`、`oc.rng`→`rng`);头注「耦合边界」段改写(束注入+签名扩展+随编排器每战新建同灭语义不变) +- [ ] grant_segment.gd 重写:`_init(bundle: Dictionary)` 断言 12 键解包 12 成员(第 4 节分配表);54 处改址——除上表映射外加:`oc._reward_economy`→`reward_economy`、`oc.minesweeper`→`minesweeper`、`oc._hero_atk()`→(无此调用)、`oc._feat_yield_adjust(...)`→`reward_grant.feat_yield_adjust(...)`(:99/:140)、`oc._harmful_variants`→`minesweeper.harmful_variants`(:87)、`oc._harmful_adjacent`→`minesweeper.harmful_adjacent`(:339)、`oc._hits_of`→`DamageController.hits_of`(:110/:115/:138/:356)、`oc.attune_param_sum("rap_transfer_mult")`→`int(attune_param_sum_cb.call("rap_transfer_mult"))`(:280)、`oc.perfect_sweep_earned()`→`bool(perfect_sweep_cb.call())`(:284)、`oc._damage._emit_hero_damage_taken(...)`→`damage.emit_hero_damage_taken(...)`(:197);:82-84 改 `var is_new_type := fx_host.mark_new_resource_type(ctype)`;:169-170 与 :378-379 改 `fx_host.add_bonus_delta(String(h.get("axis", "")), int(h.get("delta", 0)))`;头注改写 +- [ ] battle_fx_host.gd 新增两公开累积方法(成员零增,头注类变量封闭面句不动):`func mark_new_resource_type(ctype: String) -> bool`——`if ctype == "": return false`;`if _fx_new_resource_types.has(ctype): return false`;置位后 `return true`(空串短路边界=原 :82 形态逐位等价)。`func add_bonus_delta(axis: String, delta: int) -> void`——`if _fx_bonus_delta.has(axis): _fx_bonus_delta[axis] += delta` +- [ ] combat_segment.gd 重写:`_init(bundle)` 断言 10 键解包;23 处改址(映射同上+`oc._fatal`→`fatal_cb.call`、`oc._status_effects`→`status_effects`、`oc._hero_atk()`→`damage.hero_atk()`);`oc._hits_of` 行随 3.1+3.2 批已删——复核以 grep 为准;头注改写 +- [ ] aura_segment.gd(成员 `var emit_composition_cb: Callable`,:15-16 改 `emit_composition_cb.call("hero", ri)`/`("enemy", ri)`)、decay_segment.gd(成员 status_effects+emit_row_cb)、verdict_segment.gd(成员 units+四回调,:18/:20 `units.hero_unit()`/`units.query_alive("enemy")`、:22 `emit_snapshot_cb.call(verdict)`、:25/:29 `battle_over_cb.call(...)`、:32 `exit_distribution_cb.call()`)三件重写+头注改写 +- [ ] battle_refresh_flow.gd 重写:去 static——`_init(bundle: Dictionary)` 断言 8 键(facts/db/action_economy/fx_host/reward_economy/minesweeper/install_cb/grant_seg)解包;`_effective_refresh_cost()` 无参实例方法(:15-20 体逐字,`oc.db`→`db`、`oc.fx_host().fx_emit`→`fx_host.fx_emit`);`can_refresh(battle_result: String) -> bool`(:24-28 体逐字,`oc.battle_result`→参数、`oc._facts.refresh_used`→`facts.refresh_used`);`execute(battle_result: String, round_index: int) -> bool`(:32-43 体逐字——`oc._facts.refresh_used += 1`→`facts.refresh_used += 1`、`oc._reward_economy.retire_mapping()`→`reward_economy.retire_mapping()`、`oc.minesweeper.retire_board(true)`→`minesweeper.retire_board(true)`、`oc._install_and_reset(true)`→`bool(install_cb.call(true))`、`oc._rounds._grant_seg.apply_board_refreshed(oc.round_index)`→`grant_seg.apply_board_refreshed(round_index)`);头注「调用路径」句改写(编排器单行转发形态不变) +- [ ] battle_orchestrator.gd 收口::598-599 `return BattleRefreshFlow.can_refresh(self)`→`return _rounds.refresh_flow().can_refresh(battle_result)`;:606-607 →`return _rounds.refresh_flow().execute(battle_result, round_index)`;:262 `roll_round_actions()`→`roll_round_actions(round_index)`;:447 `settle_if_due()`→`settle_if_due(battle_result, round_index)`;:593 →`roll_round_actions(round_index)`;`can_refresh`/`player_request_refresh`/`_on_round_end`/`begin_battle`/`_exit_distribution` 五处体注释同步 +- [ ] 测试适配:settle_segments_test.gd :20-24 五段直构断言改束形态(以真实编排器协作件组装束逐段 `new(bundle)` 成功断言);:28-34 宿主回指断言 6 条改同一性断言(`oc._rounds._grant_seg.facts == oc._facts`、`oc._rounds._combat_seg.fx_host == oc.fx_host()` 等——同一性强度对应回指,削减弱化申报 1);adventure_feats_test.gd :671/:691/:727 `orch._hits_of(...)` → `DamageController.hits_of(...)`(削减弱化申报 2) +- [ ] 孤立验证新增段 → 出红只跑红件最小单元 → 并入全套(回归措辞:里程碑卡出口跑一次全套闸;卡内修复只做出红最小单元的最窄确认);本卡出口=golden 快照绿+battle_settlement 套件全绿+冒烟全绿 + +**T3 断点与存档公开面**(估时 0.5 工作日;区间 0.5–0.75) +取用:T1 底账。产出:处 3+处 4 清零。 + +- [ ] breakpoint_store.gd 新增公开方法面(13 个,成员零增——类变量 15 贴顶):`func bind_save_manager(sm) -> void`、`func save_manager()`(读投影,可 null)、`func set_pending_next_level(v: bool) -> void`/`func pending_next_level() -> bool`、`func set_loadout_seeded(v: bool) -> void`/`func loadout_seeded() -> bool`、`func set_resume_bp(bp: Dictionary) -> void`/`func clear_resume_bp() -> void`/`func resume_bp() -> Dictionary`(返引用零拷贝——宿主读侧只读)、`func bp_read(key: String, bp: Dictionary, fallback: Variant = null) -> Variant`(=_bp_read 更名公开化,:160 内部调用点随改)、`func set_last_level_payload(payload: Dictionary) -> void`/`func last_level_payload() -> Dictionary`、`func set_last_treasure_cleared(v: int) -> void`/`func last_treasure_cleared() -> int`(方法体一律一行转发自有成员,零逻辑增量) +- [ ] adventure_runner.gd 37 处改址(逐处)::107/:157/:180/:185/:241/:438 → `set_pending_next_level(...)`;:235 → `pending_next_level()`;:115/:191/:201 → `set_loadout_seeded(false)`;:300-301 → `loadout_seeded()`/`set_loadout_seeded(true)`;:189 → `set_resume_bp(bp.duplicate(true))`;:388 → `clear_resume_bp()`;:302/:376/:377/:378 → `resume_bp()`(读侧零拷贝语义不变);:168/:302/:377/:378/:412 `_bp_read` → `bp_read`;:220 → `bind_save_manager(sm)`;:325-326 → `var sm = _bp_store.save_manager()` 后 `if sm != null: first = not sm.meta_state.career_state()...`;:421 → `set_last_level_payload(payload.duplicate(true))`;:464/:467-468 → `last_level_payload()`;:430 → `set_last_treasure_cleared(...)`;:456 → `last_treasure_cleared()`;:474-476 → `var sm = _bp_store.save_manager()` 后 `sm.clear_breakpoint()`/`sm.write_to_disk()`;:37 头注自述句核改(「宿主读写经件」落实后注释与实态一致) +- [ ] slot_store.gd:新增 `func active_path() -> String: return _path`(读投影——has_write_target :53 同族);`_migrate_legacy_save` 更名 `migrate_legacy_save` 公开化(:150 体逐字;禁留旧名壳) +- [ ] save_manager.gd 九行改址::51 → `slots.migrate_legacy_save(...)`;:66/:69/:105/:111/:118/:119/:285/:286 `slots._path` → `slots.active_path()`(:118-119 两处同名调用间 `_path` 无变更窗口——单线程同步段,逐位等价) + +**T4 效果宿主累积面与配置挂载面**(估时 0.375 工作日;区间 0.25–0.5) +取用:T2(grant 已改指)。产出:处 5 清零(本卡 T2 已落 grant 改址与 battle_fx_host 两方法——本卡复核其孤立验证读数)。 + +- [ ] 复核 T2 步骤中 battle_fx_host.gd 两方法与 grant_segment.gd 四处改址已落(T2 内联实装——本卡不重复列);孤立验证:grant_segment 相关套件(seal_polarity/round_flow)出红最小单元 +- [ ] board_gen_table.gd / enemy_table.gd / difficulty_table.gd 各新增 `func bind_resolver(resolver: ConfigDbResolver) -> void`(体一行 `_resolver = resolver`;三件注解同型) +- [ ] config_db.gd:157-159 三行改 `combat.board_gen.bind_resolver(_resolver)` / `combat.enemy.bind_resolver(_resolver)` / `run.difficulty.bind_resolver(_resolver)`(_assign_loaded 装配序零变化) + +**T5 结构性扫描与批收口**(估时 0.375 工作日;区间 0.25–0.5) +取用:全部前卡。产出:五处结构性恒零证据+批收口两件。 + +- [ ] 新增 tests/unit/core/encapsulation_sweep_test.gd(extends SceneTree+Kit.check,全类型标注;源读取手法沿 player_copy_sweep_test 源 token 扫描先例)——七段断言组,全部带「扫描面非空前置+正锚」: + ①七段文件集(settlement/ 七 .gd)逐件:文件存在且非空+含对应 `class_name` 正锚+`\boc\b` 全文零命中〔封装5.1 V2〕 + ②battle_orchestrator.gd:非空+`func _hero_atk|func _feat_yield_adjust|func _harmful_variants|func _harmful_adjacent|func _hits_of` 零命中(五方法零残留)〔封装5.1 V3〕 + ③adventure_runner.gd:非空+`_bp_store\._` 零命中+`_bp_store.bp_read(` 正锚(新面在用)〔封装5.1 V4〕 + ④save_manager.gd:非空+`slots\._` 零命中+`slots.active_path()` 正锚〔封装5.1 V5〕 + ⑤grant_segment.gd:非空+`_fx_new_resource_types|_fx_bonus_delta` 零命中+`mark_new_resource_type(` 正锚〔封装5.1 V6〕 + ⑥config_db.gd:非空+`\._resolver\s*=` 零命中+`bind_resolver(_resolver)` 正锚〔封装5.1 V7〕 +- [ ] run_all.gd manifest 追加 2 行:settlement_wiring_snapshot_test(expect 0,注记「R1 同种子逐项 golden 对拍主证〔封装5.1〕」)+encapsulation_sweep_test(expect 0,注记「R1–R6 结构性零命中扫描〔封装5.1〕」) +- [ ] **实现报告** `reports/iter-实现报告-<日期>.md`:各卡状态+S13 键改前改后对账表(T1 基线逐件核)+golden 改前改后对拍读数+实现决定记录(代拍板白名单逐条回填) +- [ ] **反哺点清单** `reports/iter-反哺点-<日期>.md`:第 6 节同步面表逐条落点(architecture.md 八行登记内容、GDD/术语确认行) +- [ ] 批末核对:game/tests/README.md 能力名与对照表引用一致(本卡零编辑);独立验收审计(第 8 节末)未过不合并;.uid 收口=`--editor --quit` 一次后确认 2 件新测试件 .uid 已生成随批提交 + +### 估时汇总 + +T1 0.25|T2 1.25|T3 0.5|T4 0.375|T5 0.375。 +区间合计 2.25–3.75 工作日;**精确汇总 2.75 工作日**(切分预案:若 T2 超 1.5 工日,把 T3 切出为独立半日卡顺延,其余不动;合计超 3 工作日=超卡面估时域,须用户确认后方可续批)。 + +## 8. 验证闸(改动—验收对照表) + +测试方式两分法:下表全部走**调试接口验证**(单元/集成套直构夹具与真实入口调用);**正常流程体验验证**=零项(零行为变更批,无目检点——实机观感逐位同改前)。判据全部绑被测改动特有的可观测提交面(同种子行流逐位/束引用同一性/源码零命中带非空前置与正锚)。 + +| 需求点 | 改动(文件:行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 | +|---|---|---|---|---|---|---| +| R1 七段解耦+束交付 | settlement 七文件重写+battle_orchestrator 束组装与三调用点+RoundCycle/BattleRefreshFlow 形态换代 | settlement_wiring_snapshot_test.gd:_init 主对拍〔封装5.1 V1〕;settle_segments_test.gd 束构造与同一性断言;round_flow_skill_pool_test/seal_polarity_test/refresh_feats_test 既有全套回归 | 单元+集成 | `BattleOrchestrator.begin_battle()`→`MinesweeperRules.settle_batch()`→`player_request_refresh()`(全程公开入口) | 同种子行流与快照逐位同 golden(改前固化);段持注入引用==编排器实例同一性;`\boc\b` 七文件零命中 | 既有:轮内流与结算五段全序 | +| R2 搬家五方法归位 | damage_controller +hero_atk/hits_of/emit_hero_damage_taken 公开化+facts 成员;reward_grant +feat_yield_adjust;minesweeper_rules +harmful_variants/harmful_adjacent;编排器五方法删除+:282 改指 | settlement_wiring_snapshot_test〔封装5.1 V1〕(五方法消费路径全在行流内——主角攻击 base_value/奖励乘区/terrain_kind 事实/奥术矢开单);roll_multiplier_test.gd:_smoke_hero_atk_derived 既有回归;adventure_feats_test hits_of 面回归;encapsulation_sweep_test 编排器五方法定义零命中〔封装5.1 V3〕 | 单元 | `begin_battle()`(enc hero_atk override→spawn→攻击单)/授予段真实结算链 | 攻击单基值随 enc override 走(派生读贯通);行流逐位同;五方法宿主定义唯一(编排器零残留) | 既有:伤害公式与掷点乘区 | +| R3 grant→BattleFxHost 累积方法 | battle_fx_host +mark_new_resource_type/+add_bonus_delta;grant :82-84/:169-170/:378-379 改址 | seal_polarity_test/round_flow_skill_pool_test 既有全套回归(血税 bonus_delta 与地质学家 new_resource_type 两订阅行行为面);encapsulation_sweep_test grant 私键零命中+正锚〔封装5.1 V6〕 | 单元 | 授予段真实结算链(mine_hit/seal_hit fx 发射→施加面) | bonus_delta 轴累积值与 new_resource_type 首见判定逐位同;grant 源零私键直写 | 既有:封印与极性路由/不可逆 | +| R4 adventure_runner→BreakpointStore | breakpoint_store +13 公开方法面(_bp_read 更名 bp_read);adventure_runner 37 处改址 | save_rng_roundtrip_test.gd:_test_old_version_save_migrates_and_resumes+:_test_disk_roundtrip_preserves_breakpoint 既有回归(断点组装/回放/续玩全链真实入口);encapsulation_sweep_test `_bp_store\._` 零命中〔封装5.1 V4〕 | 单元+集成 | `AdventureRunner.resume_adventure()`/`start_adventure()`→`write_to_disk()`/`load_from_disk()` | 断点续玩逐位同(27 键冻结);adventure_runner 源零 `_bp_store._` 直读写 | 既有:旧档迁移链与断点续玩零跳号(集成) | +| R5 save_manager→SlotStore | slot_store +active_path/_migrate 更名公开化;save_manager 九行改址 | save_manager_domain_test.gd:_smoke_save+save_slot_isolation_test 既有回归;encapsulation_sweep_test `slots\._` 零命中〔封装5.1 V5〕 | 单元 | `SaveManagerCore.write_to_disk()`/`load_from_disk()`/`_ready()` 迁移口 | 写盘/读回/迁移路径逐位同(tmp+rename 原子序不变);save_manager 源零 `slots._` | 既有:存档写盘⇄读回往返保真 | +| R6 config_db→三表挂载 | 三 schema +bind_resolver;config_db :157-159 改址 | config_db_resolver_test.gd 既有全套回归(_test_rowset_order_preserved/_test_row_kind_routing/_test_difficulty_clamp——resolver 注入后解析面逐位同);encapsulation_sweep_test `\._resolver =` 零命中+正锚〔封装5.1 V7〕 | 单元 | `ConfigDB.load_tables()`(装配段)→`ConfigDbResolver.resolve_*()` | 行集解析/难度 clamp 逐位同;config_db 源零 `_resolver` 直写 | 既有:行集寻址、行序保序与难度乘数 clamp | + +**零行为改动面的证据义务**:本卡全部六行均为非行为改动(零行为变更批)——不设「行为改动」行;每行的零变更证明=T1 golden 同种子逐项比对(改前固化、改后全程绿)+既有套件零转红+结构性 sweep 恒零。能力行全部「既有」、零新增——判断依据:本批零行为变更=玩家可观测能力面零变化,无新能力可登记;受影响存量行的真实入口与代表用例名零变化(settle_segments_test/adventure_feats_test 文件名与其在册引用不变),故能力清单零编辑(批末核对义务在 T5)。 + +**闸口径**:重闸=`tools/run_all_gates.sh` 按本批改动域选档(改动含 game/ 下非 .md 行为载体 → `--code`);所选域全绿才合并。卡内不写死闸件名单。回归措辞:里程碑卡(T 段)出口跑一次全套闸;卡内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套。 + +**测试削弱申报**(允许改/删的旧断言全清单;未申报的删改由独立验收审计判红): +1. settle_segments_test.gd:20-24 五段直构断言——构造签名换代(host 三参/单参 → 束单参),断言对象从构造签名改束构造成功;段类可独立实例化的断言意图保持,强度不减(R1)。 +2. settle_segments_test.gd:28-34 宿主回指断言 6 条(`.oc == oc`)——段类对编排器引用归零后回指对象消失;改注入引用同一性断言(段持 facts/fx_host==编排器实例),装配面断言意图保持,强度不减(R1)。 +3. adventure_feats_test.gd:671/:691/:727 `orch._hits_of(...)` → `DamageController.hits_of(...)`——方法搬家改址,断言内容(attack_bonus 命中过滤)零改动(R2)。 +以上 3 条均为「随被测改动同步的引用形态迁移」,无一条删除断言或放宽阈值。 + +**独立验收审计**:入口=批末 T5 后、合并前;报告=`reports/iter-验收审计-<日期>.md`;由没参与实现的会话或子代理执行,核对:对照表逐行断言真实存在且在当轮跑批通过、golden 改前改后对拍读数在案、测试削弱申报 3 条之外零删改、第 13 节无效成员零残留、S13 键只降不升对账。未过不合并。 + +## 9. 异常分级 + +- **L1 自救**:测试断言笔误、束键名拼写、注释错字、改址遗漏一处编译级报错的就地修复——就地改,记录进实现报告。 +- **L2 记录继续**:行号 ±5 行内的漂移(以 grep 符号锚定位后继续);测试失败经排查属既有缺陷且与本批改动无因果——登记跳过并报用户。 +- **L3 停机写报告等用户**:①卡面与处置记录冲突、或处置记录未落盘/与本卡第 3 节不一致(上游缺陷,退写卡段);②golden 改后读数与改前基线出现任何非预期漂移(零行为变更契约被破=上游缺陷停卡,禁就地调和);③束形态与 S13 预算互斥——任一触件成员数超第 14 节预算(RoundCycle 15/BattleFxHost 15/BreakpointStore 15/orchestrator 15 四贴顶件禁再增成员)=上游缺陷停卡退写卡段,禁实现段自行拆件或砍面;④实现中发现第 4 节未登记的第五处编排器私取消费面或搬家方法第 4 个调用方(行为语义不明,禁代裁);⑤机检键与卡片契约互斥(含 schema 校验/静态闸判据冲突)=一律停卡呈报,不得自造第三条路。 + +## 10. 代拍板白名单 + +- 测试内部夹具命名与组织(束组装辅助函数名、golden 序列化键序、sweep 正则的具体写法——判据面不变)。 +- 注释与断言消息中文措辞微调(尾缀〔封装5.1 Vn〕与判别词保留)。 +- 段类/编排器头注的改写措辞(模块介绍职责不变)。 +- 束 assert 缺键报错文案(「引用束缺键」判别词保留)。 +- 逐卡内「孤立验证→出红最小单元→并入全套」的执行顺序细节。 +- T1 golden 转储通道的实现方式(打印格式/临时旗标,用后即删)。 +超清单的决断记入实现报告「实现决定记录」节。 + +## 11. 待裁点 + +**零待裁点,开工门=U0**——五处修复方案、段类终态(六子对象+七回调+段间引用+公开读数注入+对编排器零引用)、搬家五方法宿主、出卡边界、排序义务均已在 2026-11-03 设计讨论会话由用户裁决;束键分配、回调精确签名、T 卡分解、验收断言由本卡写卡期实查定死(第 3/4/7 节)。本卡未新增任何备选案。 + +## 12. 落位与可复用性预检 + +**新增文件(2 件,全部测试件)**: +- tests/unit/battle_settlement/settlement_wiring_snapshot_test.gd——为什么不能复用:同种子逐项 golden 对拍需冻结改前全行流为常量基线,既有套件(round_flow_skill_pool 等)断言的是段内序与行为面、无整流 golden;battle_settlement 目录落点(夹具对象=战斗结算全链);grep 同名零命中。驱动夹具复用既有件:ConfigDBScript 显式构造+AutoPlayer.choose_dig(roll_multiplier_test.gd:14-16 同款装配先例,引用不复制)。 +- tests/unit/core/encapsulation_sweep_test.gd——为什么不能复用:五处结构性零命中是本批特有扫描面(七文件集+五方法残留+四处私取模式),player_copy_sweep_test 扫的是 presentation 文案面——**复用其源 token 扫描手法但不并件**(并件会让两批扫描面与尾缀语义混乱)。唯一落点 tests/unit/core;grep 同名零命中。 + +**新增函数/成员(逐条唯一性核查,grep 同名全库实核)**: +- `DamageController.hero_atk`/`hits_of`/`emit_hero_damage_taken`——编排器 `_hero_atk`/`_hits_of` 改名迁移非并存(禁别名);`_emit_hero_damage_taken` 去下划线公开化非新增体;`facts` 成员为该件第 13 个类变量(预算内)。grep `func hero_atk`/`func hits_of` 全库零第二处。 +- `RewardGrant.feat_yield_adjust`——`_feat_yield_adjust` 改名迁移;RewardGrant 持 reward_economy 引用(:22 既有)故体零改动可行。grep 唯一。 +- `MinesweeperRules.harmful_variants`/`harmful_adjacent`——改名迁移;db 为构造参(:44 既有)。grep 唯一。 +- `BattleFxHost.mark_new_resource_type`/`add_bonus_delta`——新方法旧账面(成员零增);grep 同名零命中,命名与既有 apply_ac_bonus/counter_add 动词族同型。 +- `SlotStore.active_path`——grep 全库零同名;has_write_target 同族读投影。 +- `BreakpointStore` 13 方法——grep `pending_next_level|loadout_seeded|resume_bp|last_level_payload|last_treasure_cleared|bp_read|bind_save_manager` 作为**方法名**全库零命中(现仅为成员名);成员到方法一一对应,无第二落点。 +- 三 schema `bind_resolver`——grep 零同名;参数类型 ConfigDbResolver 与 config_db.gd:43 既有协作类同一实例。 +- `RoundCycle.refresh_flow`——grep 零同名;读出口与 stats()/wallet() 组件出口先例同型(adventure_runner.gd:60-82)。 + +**复用既有(不新增)**:束注入形态=BoardInstaller/BattleFxHost/RewardGrant/BreakpointStore 四先例;读投影 Callable=attune_safe_seen_cb/pool_effective_cb/facts_cb 三先例;源扫描测试=player_copy_sweep_test 手法;manifest 登记=run_all.gd 既有条目族。零新增生产文件(全部落在既有件——架构七段结构零改动的直接后果)。 + +**分层与交互面**:段类→六子对象/协作件=既有 B1 域内调用关系(architecture.md:119 B2/B3/B4 全调用面唯一调用方=B1 域文件集——S7_B1_SET 已含七段,零新增跨域路径);段类→编排器=单向 Callable(禁双向强引用);三 schema bind_resolver=既有 config_db→schema 装配方向(:131-159 同向,禁反向);RngService 红线零触碰(本批零新增随机源);Core 零 UI 红线零触碰(全套件 --headless 可跑);数值单一事实源零触碰(零表改动)。 + +## 13. 禁为机检文本保留无效成员 + +本卡为重构类卡,全卡适用以下条款(code-conventions §1.1 ⑤同款):禁止为迎合机检消息文本(含计数、sweep 正则、grep 面)而保留或新增无效成员/别名/转发壳;搬家五方法宿主原方法删除后禁留同名或别名转发壳;`_migrate_legacy_save` 更名后禁留旧名壳;`_bp_read` 更名后禁留旧名壳;`_emit_hero_damage_taken` 公开化后禁留私有旧名;BreakpointStore 新方法面禁在成员外另立镜像账本。机检键与卡片契约互斥时(如 S13 贴顶件、sweep 正则与签名冲突),实现段一律停卡呈报,不得自造第三条路。 + +## 14. 实现规范预算 + +新增 .gd 文件仅 2 个测试件(SceneTree 测试脚本,全类型标注、零公开生产面——接口块预算余量充足)。生产代码全部落既有件,按「存量触面一查」逐件对账(S13 默认阈值:公开方法 ≤20/类变量 ≤15/分支 ≤8/返回 ≤6): + +- **贴顶四件(禁再增成员,T1 读数锁定)**:battle_orchestrator.gd 15(本批成员零净增——五方法删除不涉成员);round_cycle.gd 8→15(束解包 7+_refresh_flow 1+既有 7——贴顶,头注记「贴顶禁再增」);battle_fx_host.gd 15(零增,方法-only);breakpoint_store.gd 15(零增,方法-only)。 +- **类变量净增件**:grant_segment 3→12、combat_segment 3→10、verdict 1→5、aura 1→1、decay 0→2(aura/decay 按 1/2 计——现各持 oc 一员)、battle_refresh_flow 0→8、damage_controller 12→13——全部 ≤15。 +- **公开方法净增件**:minesweeper_rules 18→**20 贴顶**(+2)、damage_controller 10→13(+hero_atk/hits_of/emit_hero_damage_taken 公开化)、reward_grant 9→10、battle_fx_host 16→18、slot_store 10→11、breakpoint_store 5→18、RoundCycle 3→4、三 schema 各 +1——全部 ≤20。 +- **迁移函数对账**:搬家五方法+`_migrate_legacy_save`+`_bp_read`+`_emit_hero_damage_taken` 逐个查 `tools/gdstyle_baseline.txt` 源键——基线无此 8 键(默认阈值内),迁移即原体;若 T1 读数发现任一源函数 branches/returns 超默认登记值,迁移即拆函数(拆分不改语义,不算迎合机检——与第 13 节区分)。 +- **存量触面 S13 预期**:本卡触件 15 件(第 3.2 节清单)S13 键较 T1 现场基线**只降不升**(净删为主:五方法约 45 行迁出、107 处 oc._ 改址不增行数;净增面=两累积方法+13 bp 方法面+束解包成员行);adventure_runner 既有登记键(类变量 23)照登对账零变化。降不达即检查是否夹带超预算成员,L3 ③兜底。 +- **指标例外申报**:无(零新件、零超默认阈值新增面;若实现中发现例外,走本卡异常分级 L3 ③停卡,禁就地豁免)。 + +## 15. 拆分边界纪律 + +见第 4 节红线(结构类卡必填条款,判据权威=code-conventions §1.1):本卡零新拆件——段类七件、RoundCycle、BattleRefreshFlow、DamageController、RewardGrant、MinesweeperRules、BattleFxHost、BreakpointStore、SlotStore 全部架构在册既有件,本批只做接线形态换代与五方法归位。逐件职责语句不变:五段段类=B1 每轮结算序列的分段逻辑件(architecture.md:127)、RoundCycle=轮结算周期推进结构单点(:125)、BattleRefreshFlow=换图刷新流程唯一承载(:123)、五方法归位=各领域宿主既有职责面内的原语归位(伤害基值派生读归伤害管线、奖励乘区调整归授予管线、地形伤害型变异过滤归棋盘状态域、效果命中过滤归伤害域)。单一变化原因=封装边界(跨对象私取清零),非阈值驱动。禁凑计数袋:段类成员束解包以消费面为准(第 4 节分配表逐段列明),无「剩下的成员」式打包。先例=迭代 41 两卡 v1.2(核心数据面契约 7/呈现层契约 9)。 diff --git a/待办清单.md b/待办清单.md index f185a3f8..d7537792 100644 --- a/待办清单.md +++ b/待办清单.md @@ -20,6 +20,8 @@ **2026-11-02 写卡(2026-11-03 修订闭合)**:需求卡片 reports/需求卡片-架构审查3.1+3.2整改批-2026-11-02.md(v1.2——子代理写卡+grilling 一轮 19 条折入+godot-master 式终审 4 条折入,pipeline_gate PASS,worktree 提交 2f43b81d);11 张 T 卡估时合计 8 工作日(超 10 须特批提示在卡);能力行 10 增 5 改 1 删已入 game/tests/README.md。 +**2026-11-03 设计闭合+写卡(5.1 封装修复部分)**:2026-11-03 会话对审计 §5.1(settlement 段类私取编排器私有成员)完成设计讨论并扩面普查,裁决五处跨对象私有访问修复方案(settlement 七段→编排器束交付/搬家五方法/adventure_runner→BreakpointStore/save_manager→SlotStore/grant_segment→BattleFxHost+config_db→三表容器;presentation 层约 227 行另开设计讨论不在内)。凭据=reports/处置-架构审查5.1封装修复-2026-11-03.md(处置记录,与本卡并行成文)+审计报告 §5.1+architecture.md:119/:124/:137-146。需求卡片 reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md(v1.0——5 张 T 卡估时精确汇总 2.75 工作日;零行为变更批,能力清单零新增行已写明判断依据);实现排序在 3.1+3.2 卡之后(combat_segment 同文件避让)。 + **改动面**:文档+游戏代码+工具代码 **状态**:文档设计已闭合+已写卡+已编迭代 50 From 277ca158db4d0e3b00033cc707d71883615540ed Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 3 Nov 2026 06:03:38 +0800 Subject: [PATCH 03/19] =?UTF-8?q?=E6=96=87=E6=A1=A3=E8=AE=BE=E8=AE=A1(?= =?UTF-8?q?=E6=9E=B6=E6=9E=84=E5=AE=A1=E6=9F=A55.1=E5=B0=81=E8=A3=85?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=C2=B7=E4=BF=AE=E6=AD=A3):=20=E5=A4=84?= =?UTF-8?q?=E7=BD=AE=E8=AE=B0=E5=BD=95=E4=B8=A4=E7=AC=94=E8=AE=A2=E6=AD=A3?= =?UTF-8?q?=E2=80=94=E2=80=94=E2=91=A0=E6=8E=A5=E6=94=B6=E6=96=B9=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E5=AE=9E=E5=90=8D=E8=A1=A5=E3=80=8C=E6=89=B9=E3=80=8D?= =?UTF-8?q?=E5=AD=97(reports/=E9=9C=80=E6=B1=82=E5=8D=A1=E7=89=87-?= =?UTF-8?q?=E6=9E=B6=E6=9E=84=E5=AE=A1=E6=9F=A55.1=E5=B0=81=E8=A3=85?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=89=B9-2026-11-03.md,=20=E5=86=99=E5=8D=A1?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E8=90=BD=E7=9B=98=E6=A0=B8=E5=AE=9E);=20?= =?UTF-8?q?=E2=91=A1=E6=99=AE=E6=9F=A5=E5=A4=842=20adventure=5Frunner?= =?UTF-8?q?=E2=86=92BreakpointStore=20=E8=AF=BB=E6=95=B0=E6=8C=89=E5=86=99?= =?UTF-8?q?=E5=8D=A1=E4=BB=A3=E7=90=86=E5=AE=9E=E6=A0=B8=E6=94=B9=2037?= =?UTF-8?q?=E5=A4=84/32=E8=A1=8C(=E9=A6=96=E7=89=88=E8=AE=B037=E8=A1=8C?= =?UTF-8?q?=E2=80=94=E2=80=945=E8=A1=8C=E5=90=84=E5=90=AB2=E5=A4=84?= =?UTF-8?q?=E8=AE=BF=E9=97=AE),=20=E5=8F=96=E8=AF=81=E6=B3=A8=E6=84=8F?= =?UTF-8?q?=E8=A1=8C=E5=90=8C=E6=AD=A5=E7=99=BB=E8=AE=B0;=20=E5=85=B6?= =?UTF-8?q?=E4=BD=99=E9=9B=B6=E6=94=B9=E5=8A=A8;=20=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E5=9F=9F=E9=97=B8=E5=A4=8D=E8=B7=91=E5=85=A8=E7=BB=BF(8?= =?UTF-8?q?=E9=97=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- reports/处置-架构审查5.1封装修复-2026-11-03.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reports/处置-架构审查5.1封装修复-2026-11-03.md b/reports/处置-架构审查5.1封装修复-2026-11-03.md index 5e5f3b61..71969bb8 100644 --- a/reports/处置-架构审查5.1封装修复-2026-11-03.md +++ b/reports/处置-架构审查5.1封装修复-2026-11-03.md @@ -1,6 +1,6 @@ # 处置:架构审查 5.1 封装修复批(2026-11-03) -> **性质**:设计讨论段过程稿(裁决记录+取证事实)。**接收方**=reports/需求卡片-架构审查5.1封装修复-2026-11-03.md + 待办清单条目「架构审查优化讨论——全库架构审计读数的逐条裁决与整改分批」(2026-10-29 登记)。**寿命**:需求卡片成立即退役(吸收即死——结论吸收进卡片与 code-conventions,未决迁待办清单)。 +> **性质**:设计讨论段过程稿(裁决记录+取证事实)。**接收方**=reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md + 待办清单条目「架构审查优化讨论——全库架构审计读数的逐条裁决与整改分批」(2026-10-29 登记)。**寿命**:需求卡片成立即退役(吸收即死——结论吸收进卡片与 code-conventions,未决迁待办清单)。 > **输入**:reports/审计-全库架构审查-2026-10-29.md §5.1(settlement 五段类直读写编排器私有成员;讨论段把普查扩到全库同模式面)+ 2026-11-03 讨论会话用户逐项裁决 + 2026-11-03 会话取证(19 符号逐个核过、行号为当日现址——行号写卡段复核)。 ## 一、总判据(用户 2026-11-03 裁,本批一切设计遵循) @@ -25,7 +25,7 @@ ## 三、普查五处(core 层;2026-11-03 会话取证现址,行号写卡段复核) 1. **settlement 七段→编排器**:105 行/107 处/19 符号(七段=五段段类+round_cycle+battle_refresh_flow)。分布=grant_segment 54/combat_segment 23/round_cycle 10/verdict_segment 9/battle_refresh_flow 5/aura_segment 2/decay_segment 2。构成=成员引用 72 处+编排器方法 35 处(逐符号与修后归属见五、总表)。 -2. **adventure_runner→BreakpointStore**:37 行直读写(_pending_next_level、_loadout_seeded、_resume_bp、_save_manager、_last_level_payload、_last_treasure_cleared、_bp_read)——adventure_runner.gd:37 注释自述「宿主读写经件」未落实。 +2. **adventure_runner→BreakpointStore**:37 处直读写/32 行(5 行各含 2 处访问;_pending_next_level、_loadout_seeded、_resume_bp、_save_manager、_last_level_payload、_last_treasure_cleared、_bp_read)——adventure_runner.gd:37 注释自述「宿主读写经件」未落实。 3. **save_manager→SlotStore**:9 行(slots._path 直读写 ×8+slots._migrate_legacy_save 私有方法调用;save_manager.gd:51/66/69/105/111/118-119/285-286)。 4. **grant_segment→BattleFxHost**:6 行直写 _fx_new_resource_types(:82/:84)与 _fx_bonus_delta(:169-170/:378-379)。 5. **config_db→三表容器**:3 行装配期写 _resolver(config_db.gd:157-159)。 @@ -82,7 +82,7 @@ presentation 层同模式约 227 行(抽样核实、未逐行判读)—— | _emit_settlement_snapshot | 1 | 编排器私有方法(结算快照发射) | 留宿主(呈现投影出口不变) | 构造注入 Callable | | **合计** | **107 处/105 行** | — | — | — | -取证注意:成员七符号逐项加总 73、编排器方法十二符号逐项加总 34,与三、构成行记写的 72+35 有 ±1 出入(总处数 107 两路一致);行号与计数一律以写卡段复核为准。 +取证注意:成员七符号逐项加总 73、编排器方法十二符号逐项加总 34,与三、构成行记写的 72+35 有 ±1 出入(总处数 107 两路一致);普查处 2 读数按写卡代理实核修正为 37 处/32 行(首版记 37 行——5 行各含 2 处访问);行号与计数一律以写卡段复核为准。 ## 六、架构锚点(architecture.md) From 07caad9d54fe4751377d2e1ac5d8ec0eb77f781d Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 3 Nov 2026 06:37:26 +0800 Subject: [PATCH 04/19] =?UTF-8?q?=E6=96=87=E6=A1=A3=E8=AE=BE=E8=AE=A1(?= =?UTF-8?q?=E6=9E=B6=E6=9E=84=E5=AE=A1=E6=9F=A55.1=E5=B0=81=E8=A3=85?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=C2=B7=E8=A1=A5=E5=BD=95):=20=E5=8F=96?= =?UTF-8?q?=E8=AF=81=E6=B3=A8=E6=84=8F=E8=A1=8C=E8=BF=BD=E5=8A=A0=E4=B8=80?= =?UTF-8?q?=E7=AC=94=E2=80=94=E2=80=94godot-master=20=E7=BB=88=E5=AE=A1?= =?UTF-8?q?=E8=A1=A5=E6=9F=A5=E6=99=AE=E6=9F=A5=E6=BC=8F=E9=A1=B9=20SlotSt?= =?UTF-8?q?ore=E2=86=92SaveManagerCore=20=E5=8F=8D=E5=90=91=E7=A7=81?= =?UTF-8?q?=E5=8F=96=E7=BA=A613=E5=A4=84(slot=5Fstore.gd:26-28/38-39/61-76?= =?UTF-8?q?/92-97/119/129/134/159-162,=20=E7=9B=B4=E7=94=A8=20=5Fsave.=5Fr?= =?UTF-8?q?ead=5Fonly/=5Freset=5Fto=5Fdefault/=5Fdata/=5Frename=5Foverwrit?= =?UTF-8?q?e/=5Fpeek=5Fsummary=5Fat),=20=E4=B8=8E=E6=99=AE=E6=9F=A5?= =?UTF-8?q?=E5=A4=843(save=5Fmanager=E2=86=92SlotStore)=E5=90=8C=E4=B8=80?= =?UTF-8?q?=E5=AF=B9=E7=B1=BB=E7=9B=B8=E5=8F=8D=E6=96=B9=E5=90=91,=20?= =?UTF-8?q?=E5=A4=84=E7=BD=AE=E5=B9=B6=E5=85=A5=E9=9C=80=E6=B1=82=E5=8D=A1?= =?UTF-8?q?=E7=89=87T3=E5=AD=98=E6=A1=A3=E9=9D=A2(=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E5=B7=B2=E6=8A=98=E5=85=A5);=20=E6=96=B9=E5=90=91=E5=B7=B2?= =?UTF-8?q?=E6=8A=BD=E6=9F=A5=E6=A0=B8=E5=AE=9E(slot=5Fstore.gd=20=5Fsave.?= =?UTF-8?q?=5F*=20=E5=AE=9E=E5=AD=98);=20=E5=85=B6=E4=BD=99=E9=9B=B6?= =?UTF-8?q?=E6=94=B9=E5=8A=A8;=20=E6=96=87=E6=A1=A3=E5=9F=9F=E9=97=B8?= =?UTF-8?q?=E5=A4=8D=E8=B7=91=E5=85=A8=E7=BB=BF(8=E9=97=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- reports/处置-架构审查5.1封装修复-2026-11-03.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reports/处置-架构审查5.1封装修复-2026-11-03.md b/reports/处置-架构审查5.1封装修复-2026-11-03.md index 71969bb8..d7432405 100644 --- a/reports/处置-架构审查5.1封装修复-2026-11-03.md +++ b/reports/处置-架构审查5.1封装修复-2026-11-03.md @@ -82,7 +82,7 @@ presentation 层同模式约 227 行(抽样核实、未逐行判读)—— | _emit_settlement_snapshot | 1 | 编排器私有方法(结算快照发射) | 留宿主(呈现投影出口不变) | 构造注入 Callable | | **合计** | **107 处/105 行** | — | — | — | -取证注意:成员七符号逐项加总 73、编排器方法十二符号逐项加总 34,与三、构成行记写的 72+35 有 ±1 出入(总处数 107 两路一致);普查处 2 读数按写卡代理实核修正为 37 处/32 行(首版记 37 行——5 行各含 2 处访问);行号与计数一律以写卡段复核为准。 +取证注意:成员七符号逐项加总 73、编排器方法十二符号逐项加总 34,与三、构成行记写的 72+35 有 ±1 出入(总处数 107 两路一致);普查处 2 读数按写卡代理实核修正为 37 处/32 行(首版记 37 行——5 行各含 2 处访问);godot-master 终审补查出普查漏项——SlotStore→SaveManagerCore 反向私取约 13 处(slot_store.gd:26-28/38-39/61-76/92-97/119/129/134/159-162,直用 _save._read_only/_reset_to_default/_data/_rename_overwrite/_peek_summary_at),与普查处 3(save_manager→SlotStore)为同一对类的相反方向,处置去向=并入需求卡片 T3 存档面(卡片已同步折入);行号与计数一律以写卡段复核为准。 ## 六、架构锚点(architecture.md) From b5f2bfb7e789ca056b8dc1e196036df9539e0f4c Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 3 Nov 2026 06:48:08 +0800 Subject: [PATCH 05/19] =?UTF-8?q?=E5=86=99=E5=8D=A1(=E6=9E=B6=E6=9E=84?= =?UTF-8?q?=E5=AE=A1=E6=9F=A55.1=E5=B0=81=E8=A3=85=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=89=B9=C2=B7v1.1=E7=BB=88=E5=AE=A1=E6=8A=98=E5=85=A5):=20god?= =?UTF-8?q?ot-master=E7=BB=88=E5=AE=A1=E4=B8=83=E9=A1=B9=E6=8A=98=E5=85=A5?= =?UTF-8?q?=E2=80=94=E2=80=94=E2=91=A0golden=E5=B0=81=E5=8D=B0=E6=AD=A5?= =?UTF-8?q?=E6=94=B9=E5=B0=81=E6=9C=AA=E6=8F=AD=E7=A4=BA=E7=9B=B8=E9=82=BB?= =?UTF-8?q?=E6=A0=BC(=E5=B0=81=E5=8D=B0=E5=AD=90=E9=93=BE=E8=BF=9B?= =?UTF-8?q?=E4=B8=BB=E8=AF=81,=E6=8B=92=E7=BB=9D=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E5=BD=92=E6=97=A2=E6=9C=89=E5=9B=9E=E5=BD=92)=E2=91=A1?= =?UTF-8?q?=E4=B8=89schema=20bind=5Fresolver=E8=A7=A3=E6=9E=90=E5=86=92?= =?UTF-8?q?=E7=83=9F=E4=B9=89=E5=8A=A1(=E7=B1=BB=E5=9E=8B=E7=8E=AF?= =?UTF-8?q?=E5=BD=93=E8=BD=AE=E5=8D=B3=E7=82=B8,=E7=A6=81type-hint:ignore)?= =?UTF-8?q?=E2=91=A2T3=E4=B8=A4=E7=AD=BE=E5=90=8D=E8=A1=A5S9=E6=B3=A8?= =?UTF-8?q?=E8=A7=A3=E2=91=A3=E6=88=90=E5=91=98=E8=B4=A6=E4=B8=A4=E7=AC=94?= =?UTF-8?q?=E8=AE=A2=E6=AD=A3(damage=209=E2=86=9212/decay=201=E2=86=922?= =?UTF-8?q?=E2=80=94=E2=80=94=E7=BB=88=E5=AE=A1=E5=AE=9E=E6=A0=B8)?= =?UTF-8?q?=E2=91=A4harmful=5Fadjacent=E8=87=AA=E5=91=BC=E9=9A=8F=E6=9B=B4?= =?UTF-8?q?=E5=90=8D+:280-281=E6=B3=A8=E9=87=8A=E5=90=8C=E6=AD=A5=E2=91=A5?= =?UTF-8?q?=E7=8E=B0=E5=80=BC=E4=BA=A4=E4=BB=98=3D=E6=B3=A8=E5=85=A5?= =?UTF-8?q?=E5=BD=A2=E6=80=81=E4=B9=8B=E4=B8=80=E5=8F=A3=E5=BE=84=E6=B3=A8?= =?UTF-8?q?(=E8=90=BD=E5=8D=A1=C2=A72,=E9=98=B2T1=E4=B8=8E=E5=A4=84?= =?UTF-8?q?=E7=BD=AE=E8=AE=B0=E5=BD=95=E6=9C=BA=E6=A2=B0=E6=AF=94=E5=AF=B9?= =?UTF-8?q?=E8=AF=AF=E5=81=9C=E5=8D=A1)=E2=91=A6SlotStore=E2=86=92SaveMana?= =?UTF-8?q?gerCore=E5=8F=8D=E5=90=91=E7=A7=81=E5=8F=96=E7=BB=88=E5=AE=A1?= =?UTF-8?q?=E8=A1=A5=E6=9F=A521=E5=A4=84/21=E8=A1=8C=E5=B9=B6=E5=85=A5T3(s?= =?UTF-8?q?ave=5Fmanager+5=E5=85=AC=E5=BC=80=E6=96=B9=E6=B3=95+=E4=B8=A4?= =?UTF-8?q?=E6=9B=B4=E5=90=8D=E5=85=AC=E5=BC=80=E5=8C=967=E2=86=9214);=20T?= =?UTF-8?q?3=E4=BC=B0=E6=97=B60.5=E2=86=920.625=E5=90=88=E8=AE=A12.875;=20?= =?UTF-8?q?pipeline=5Fgate=20PASS(30=E6=9D=A1=E7=9B=AE/50=E6=80=BB?= =?UTF-8?q?=E8=A1=A8=E8=A1=8C/=E4=BA=A4=E5=8F=89=E6=A0=B83=E9=93=BE/?= =?UTF-8?q?=E5=8D=A1=E7=89=876=E5=BC=A0=E5=85=A8=E8=BF=87)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...€求卡片-架构审查5.1封装修复批-2026-11-03.md | 49 ++++++++++--------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md b/reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md index b8d3b88d..0010a353 100644 --- a/reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md +++ b/reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md @@ -1,7 +1,7 @@ # 需求卡片:架构审查 5.1 封装修复批(2026-11-03) 来源:待办清单「架构审查优化讨论——全库架构审计读数的逐项裁决与整改分批(2026-10-29 登记,来源=审计发现)」条目 5.1 部分(**唯一事实源**:reports/处置-架构审查5.1封装修复-2026-11-03.md——处置记录与本卡并行成文,本卡开工时该件尚未落盘;T1 首步核其已落盘且与本卡第 3 节逐条一致,冲突即 L3 停卡。设计闭合凭据=2026-11-03 设计讨论会话裁决+审计报告 §5.1+architecture.md:119/:124/:137-146)。 -状态:已写卡(v1.0,2026-11-03 成文)。改动面:游戏代码(含随逻辑写/改的测试代码)。 +状态:已写卡(v1.1,2026-11-03 修订——godot-master 终审两中等发现与四低项折入+SlotStore→SaveManagerCore 反向私取终审补查并入 T3;处置记录已落盘并与本卡第 3 节核过一致)。改动面:游戏代码(含随逻辑写/改的测试代码)。 ## 1. 目标与完成定义 @@ -12,7 +12,7 @@ | 1 | settlement 七段 → 编排器 | 七文件对编排器 `oc._` 私取 105 行/107 处/19 符号(本卡第 3 节 grep 实核) | 段类构造收引用束(六子对象+编排器公开协作件引用)+七个编排器方法回调(Callable 交付)+公开读数注入;段类对编排器引用归零 | | 2 | 编排器五个放错位置的方法 | `_hero_atk`/`_feat_yield_adjust`/`_harmful_variants`/`_harmful_adjacent`/`_hits_of` 留宿主、段类经宿主引用直调(architecture.md:145「现状形态」) | 各归领域宿主(伤害域/奖励域/地形棋盘域),宿主原方法删除禁留壳 | | 3 | adventure_runner → BreakpointStore | `_bp_store._` 直读写 37 处(32 行;adventure_runner.gd:37 注释自述「宿主读写经件」未落实) | BreakpointStore 公开方法面承接,宿主私取清零 | -| 4 | save_manager → SlotStore | `slots._path` ×8+`slots._migrate_legacy_save` 私有方法调用 ×1(save_manager.gd:51/66/69/105/111/118-119/285-286) | SlotStore 公开读投影 `active_path()`+迁移方法公开化承接 | +| 4 | save_manager ↔ SlotStore | save_manager→SlotStore:`slots._path` ×8+`slots._migrate_legacy_save` 私有方法调用 ×1(save_manager.gd:51/66/69/105/111/118-119/285-286);SlotStore→SaveManagerCore 反向私取约 13 处(slot_store.gd:26-28/38-39/61-76/92-97/119/129/134/159-162——直用 `_save._read_only`/`_reset_to_default`/`_data`/`_rename_overwrite`/`_peek_summary_at`,godot-master 终审补查) | save_manager 侧=SlotStore 公开读投影 `active_path()`+迁移方法公开化承接;SlotStore 侧=SaveManagerCore 补公开方法面承接(T3 定死) | | 5 | grant_segment → BattleFxHost;config_db → 三表容器 | grant 直写 `fx_host._fx_new_resource_types`(:82/:84)与 `fx_host._fx_bonus_delta`(:169-170/:378-379)共 6 行;config_db.gd:157-159 三行装配直写三表 `_resolver` | BattleFxHost 两个公开累积方法;三表 schema 各加公开挂载方法 `bind_resolver` | **什么状态算完**:五处的每一条改动都落码、都有第 8 节对照表配对的验收断言在当轮真实跑批中通过;主证=同种子逐项比对(改前改后动作序列快照逐位同,T1 固化、全程保持绿)+battle_settlement 套件全绿;结构性证据=core 五处跨对象私取 grep 恒零(扫描面非空前置+零命中);代码域闸全绿(冒烟+单元+探针+渲染/静态);两份 reports/ 产出物(实现报告+反哺点清单)写齐。 @@ -21,7 +21,7 @@ ## 2. 设计事实源 -- **处置记录(输入合同,逐条一致)**:`reports/处置-架构审查5.1封装修复-2026-11-03.md`——五处裁决方案、段类终态、出卡边界。本卡第 3 节现状实查与第 4/7 节签名设计是其机械承载;T1 复核两件一致(冲突=上游缺陷,L3 停卡)。 +- **处置记录(输入合同,逐条一致)**:`reports/处置-架构审查5.1封装修复-2026-11-03.md`——五处裁决方案、段类终态、出卡边界。本卡第 3 节现状实查与第 4/7 节签名设计是其机械承载;T1 复核两件一致(冲突=上游缺陷,L3 停卡)。**口径注**:处置记录「公开读数一并改注入」=形态族措辞,涵盖本卡第 4 节「调用参数现值交付」(round_index/battle_result 两变值标量构造期注入必陈旧——现值交付即注入的形态之一),T1 核对不按字面机械比对、按此口径核。 - **审计背景**:`reports/审计-全库架构审查-2026-10-29.md` §5.1(settlement 五段类直读写编排器私有成员 20+ 处;行号已漂移,以本卡第 3 节实查为准)。 - **架构登记**:`design/engineering/architecture/architecture.md`——:119(battle_orchestrator 保留面与 B1 域文件集)、:124(BoardInstaller 引用束注入先例——「构造=引用束注入(……防 _init max-parameters 新键)」)、:137-146(战斗编排域拆件定稿::140 轴丙、:141 编排器保留面登记、:143 跨件单向接线、:145 段类随动现状句)。 @@ -43,7 +43,7 @@ **处 3·adventure_runner → BreakpointStore**:`grep -o "_bp_store\._[a-z_]*" | wc -l`=**37 处**(32 行)=`_resume_bp`×8、`_pending_next_level`×7、`_save_manager`×6、`_bp_read`×5、`_loadout_seeded`×5、`_last_level_payload`×4、`_last_treasure_cleared`×2。分布:adventure_runner.gd:107/:115/:157/:168/:180/:185/:189/:191/:201/:220/:235/:241/:300-302/:325-326/:376-378/:388/:412/:421/:430/:438/:456/:464/:467-468/:474-476。BreakpointStore(breakpoint_store.gd)类变量 15(:48-63——**贴顶禁再增**,architecture.md:113 同款登记);公开方法现 5(snapshot/restore_ledger/restore_curio_state/apply_resume_params/restore_stop_bank_fragments);`_bp_read`(:196-202)内部消费点 :160。测试面:feat_vouchers_test.gd 与 meta_progression_forge_test.gd 等 12 处 `orch._rounds._grant_seg._judge_seal(...)` 直调与 `orch._rounds.mines_hits` 7 处——`_grant_seg`/`mines_hits` 成员名与归属不变,零波及。 -**处 4·save_manager → SlotStore**:save_manager.gd:51(`slots._migrate_legacy_save(LEGACY_SAVE_PATH, slots.slot_path(1), ...)`)+:66/:69/:105/:111/:118/:119/:285/:286(`slots._path` ×8)。SlotStore(slot_store.gd)`_path` :9;`_migrate_legacy_save` :150-163(唯一外部调用方=save_manager:51;件内零调用);公开读投影先例=`has_write_target()` :53-54(`_path != ""`)。SlotStore 类变量 4、公开方法 10。 +**处 4·save_manager ↔ SlotStore(双向)**:save_manager→SlotStore=save_manager.gd:51(`slots._migrate_legacy_save(LEGACY_SAVE_PATH, slots.slot_path(1), ...)`)+:66/:69/:105/:111/:118/:119/:285/:286(`slots._path` ×8)。SlotStore→SaveManagerCore 反向私取(godot-master 终审补查,2026-11-03 本会话 grep 精确实数)=**21 处/21 行**:`_save._read_only`×8(:26/:38/:65/:69/:74/:87/:91/:96)、`_save._reset_to_default`×5(:28/:39/:70/:92/:119)、`_save._data`×4(:66/:75/:88/:97)、`_save._peek_summary_at`×2(:129/:134)、`_save._rename_overwrite`×2(:159/:162)。SlotStore(slot_store.gd)`_path` :9;`_migrate_legacy_save` :150-163(唯一外部调用方=save_manager:51;件内零调用);公开读投影先例=`has_write_target()` :53-54(`_path != ""`)。SlotStore 类变量 4、公开方法 10。SaveManagerCore 私有被用面五成员=`_read_only` :23、`_data` :24、`_reset_to_default` :279、`_peek_summary_at` :217(save_manager 件内调用方 :217 定义、slot_store 两处外部)、`_rename_overwrite` :317(件内调用方 :118/:286);公开方法现 7、类变量 5。 **处 5·grant_segment → BattleFxHost+config_db → 三表容器**:grant_segment.gd:82-84(`fx_host._fx_new_resource_types.has(ctype)` 读+`[ctype] = true` 写——空串短路边界在 :82)与 :169-170、:378-379(`fx_host._fx_bonus_delta.has(axis)` 守卫+`[axis] += delta`)。BattleFxHost 类变量 15(battle_fx_host.gd:23-37——**贴顶禁再增**,头注 :10-16 自封)、公开方法 16、两私 members 无成员外读者(grep 全库仅 grant 四处)。config_db.gd:157-159 三行 `combat.board_gen._resolver = _resolver`/`combat.enemy._resolver = _resolver`/`run.difficulty._resolver = _resolver`;三表 `_resolver` 声明=board_gen_table.gd:113、enemy_table.gd:212、difficulty_table.gd:33(均无类型注解;消费点 :118/:217/:38)。表实例经 `load()` 出 .tres、无法带构造参,装配期注入是唯一时点(config_db.gd:131-159 `_assign_loaded`)。 @@ -77,7 +77,7 @@ ## 5. 范围边界 -**收件**=第 1 节表五行全部(settlement 七段解耦+搬家五方法+breakpoint_store 公开面+slot_store 公开面+battle_fx_host 两累积方法+三 schema 挂载方法,及各自的调用点改址与测试适配)。 +**收件**=第 1 节表五行全部(settlement 七段解耦+搬家五方法+breakpoint_store 公开面+存档双向公开面〔save_manager↔SlotStore 两方向〕+battle_fx_host 两累积方法+三 schema 挂载方法,及各自的调用点改址与测试适配)。 **不收件**(去向已指认): - presentation 层约 227 行私取面——**另开设计讨论**(本卡裁决范围外;去向=待办清单本条目实况,非本批)。 @@ -92,7 +92,7 @@ | 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务(反哺点清单逐条承载) | |---|---|---| -| design/engineering/architecture/architecture.md | :125 RoundCycle 行「三参直构(host/fx_host_ref/reward_grant_ref——五段构造透传不落成员)」→ 束注入+持有 BattleRefreshFlow+公开方法 3→4+类变量 8→15(贴顶);:123 BattleRefreshFlow 行 static 两入口收 oc → 实例束注入、宿主改经 RoundCycle 交接 grant_seg、类变量 0→8;:127 settlement/ 五段段类行构造形态句 → 束注入、对编排器零引用;:122 damage_controller 行实测类变量 12→13+公开面净增(hero_atk/hits_of/emit_hero_damage_taken);:121 RewardGrant 行 +feat_yield_adjust;:120 BattleFxHost 行 +两累积方法(类变量 15 不变);核心层表 A2 minesweeper_rules 行公开面 18→20(贴顶);核心层表 breakpoint_store 行公开方法面 5→18 | 反哺点清单逐条列行号与改后登记内容——**机械面文档禁直改** | +| design/engineering/architecture/architecture.md | :125 RoundCycle 行「三参直构(host/fx_host_ref/reward_grant_ref——五段构造透传不落成员)」→ 束注入+持有 BattleRefreshFlow+公开方法 3→4+类变量 8→15(贴顶);:123 BattleRefreshFlow 行 static 两入口收 oc → 实例束注入、宿主改经 RoundCycle 交接 grant_seg、类变量 0→8;:127 settlement/ 五段段类行构造形态句 → 束注入、对编排器零引用;:122 damage_controller 行实测类变量 12→13+公开面净增(hero_atk/hits_of/emit_hero_damage_taken);:121 RewardGrant 行 +feat_yield_adjust;:120 BattleFxHost 行 +两累积方法(类变量 15 不变);核心层表 A2 minesweeper_rules 行公开面 18→20(贴顶);核心层表 breakpoint_store 行公开方法面 5→18;核心层表 save_manager 行公开面 7→14(+5 承接方法+peek_summary_at/rename_overwrite 两更名公开化)+slot_store 行「双向公开面」(21 处反向私取清零) | 反哺点清单逐条列行号与改后登记内容——**机械面文档禁直改** | | design/gdd/systems/战斗循环/战斗结算.md | 无陈述变化(明细流水词表、五段段序、段边界全部零触碰——零行为变更批) | 反哺点清单写「零反哺」确认行 | | 术语表 | 无新术语(引用束注入/读投影/公开方法面均仓库现行词) | 确认行「零新增术语」 | @@ -121,8 +121,8 @@ core 层(编排域) core 层(冒险/存档域) game/core/breakpoint_store.gd 【非行为 R4】+13 公开读写方法面(成员 15 不变;_bp_read 更名 bp_read 公开化——:160 内部调用点随改) game/core/adventure_runner.gd 【非行为 R4】37 处改址(:107..:476 逐处) - game/core/save_manager.gd 【非行为 R5】:51/:66/:69/:105/:111/:118-119/:285-286 九行改址 - game/core/slot_store.gd 【非行为 R5】+active_path();_migrate_legacy_save 更名 migrate_legacy_save 公开化 + game/core/save_manager.gd 【非行为 R5】+5 公开方法(set_read_only/read_only/reset_to_default/data_snapshot/restore_data)+_peek_summary_at/_rename_overwrite 更名公开化(件内调用点随改);:51/:66/:69/:105/:111/:118-119/:285-286 九行改址 + game/core/slot_store.gd 【非行为 R5】+active_path();_migrate_legacy_save 更名 migrate_legacy_save 公开化;反向私取 21 处改址(_save._ → save_manager 公开面) game/core/config_db.gd 【非行为 R6】:157-159 三行改经 bind_resolver() game/data/schemas/board_gen_table.gd 【非行为 R6】+bind_resolver(resolver: ConfigDbResolver) game/data/schemas/enemy_table.gd 【非行为 R6】同上 @@ -144,10 +144,10 @@ core 层(冒险/存档域) - [ ] 核对实现排序在案:3.1+3.2 卡(迭代 50)未合回则本批不开工(第 1 节排序义务);combat_segment.gd 现址复核(甲案 :59-70 分支已删则以 grep 符号锚定位,行号漂移即记录进实现报告,禁改判据) - [ ] 核对处置记录 `reports/处置-架构审查5.1封装修复-2026-11-03.md` 已落盘且与本卡第 3 节逐条一致(冲突=L3 停卡) -- [ ] 新增 tests/unit/battle_settlement/settlement_wiring_snapshot_test.gd(extends SceneTree+Kit.check 主通道,全类型标注):手搭驱动=`ConfigDbScript.new()`+`load_tables("res://data/tables", true)`→`RngServiceCore` set_master_seed(4242)→`BattleOrchestrator.new(db, rng)`;捕获面=`step_row` 全量行数组+`settlement_snapshot` 全量载荷数组+`battle_finished` 载荷+收束时 `presentation_snapshot()` 关键键(round/battle_result/hero.hp/enemies.size())。驱动序(逐字定死):①`begin_battle({"level_index": 1, "node_depth": 1, "hero_hp": int(db.combat.hero.max_hp), "voucher_rap": 20})`;②轮 1:`AutoPlayer.choose_dig(minesweeper)` 返 `{dig_cell, hero_cell}` 非空则 `settle_batch([{"action": "move", "cell": hero_cell}])`→`settle_batch([{"action": "dig", "cell": dig_cell}])`→对首个已揭示安全格 `settle_batch([{"action": "seal_place", "cell": c}])`→`settle_batch([{"action": "stop"}])`;③轮 1 结算后 `player_request_refresh()`(voucher_rap=20 保证 RAP 抵折后价——覆盖换图刷新链:can_refresh/execute/install_cb/grant_seg 成功事实);④轮 2:choose_dig 一挖一停;⑤轮 3:径直 `settle_batch([{"action": "stop"}])`。断言=捕获序列与 `const GOLDEN`(行字典逐位含 type/source_class/origin_cell/round_index/display_name/value/其余载荷键)逐位相等〔封装5.1 V1〕 +- [ ] 新增 tests/unit/battle_settlement/settlement_wiring_snapshot_test.gd(extends SceneTree+Kit.check 主通道,全类型标注):手搭驱动=`ConfigDbScript.new()`+`load_tables("res://data/tables", true)`→`RngServiceCore` set_master_seed(4242)→`BattleOrchestrator.new(db, rng)`;捕获面=`step_row` 全量行数组+`settlement_snapshot` 全量载荷数组+`battle_finished` 载荷+收束时 `presentation_snapshot()` 关键键(round/battle_result/hero.hp/enemies.size())。驱动序(逐字定死):①`begin_battle({"level_index": 1, "node_depth": 1, "hero_hp": int(db.combat.hero.max_hp), "voucher_rap": 20})`;②轮 1:`AutoPlayer.choose_dig(minesweeper)` 返 `{dig_cell, hero_cell}` 非空则 `settle_batch([{"action": "move", "cell": hero_cell}])`→`settle_batch([{"action": "dig", "cell": dig_cell}])`→对首个未揭示且与主角相邻的格 c `settle_batch([{"action": "seal_place", "cell": c}])`(封印已揭示格在棋盘面必拒〔target_revealed〕——封印子链 _judge_seal_hit/_seal_hit_effects/_judge_seal_miss 及封印匠/示警烟火/完美保险扩展行必须真实进入 golden 行流;「封已揭示安全格」的拒绝路径由 seal_polarity_test 既有回归兜底,不入 golden 主证)→`settle_batch([{"action": "stop"}])`;③轮 1 结算后 `player_request_refresh()`(voucher_rap=20 保证 RAP 抵折后价——覆盖换图刷新链:can_refresh/execute/install_cb/grant_seg 成功事实);④轮 2:choose_dig 一挖一停;⑤轮 3:径直 `settle_batch([{"action": "stop"}])`。断言=捕获序列与 `const GOLDEN`(行字典逐位含 type/source_class/origin_cell/round_index/display_name/value/其余载荷键)逐位相等〔封装5.1 V1〕 - [ ] **改前取数**:本步骤在任何生产码改动之前执行——先写测试与空跑转储通道(GOLDEN 为空时打印捕获序列 JSON 后按预期码退出),在未改树上跑出 golden、填入 GOLDEN 常量、复跑全绿;golden 即改前基线读数(不构成验收,验收=改后全程保持绿) - [ ] S13 对账基线:对本卡全部 core/data 存量触件(第 14 节清单 15 件)现场跑 gdstyle 记读数为基线(既有登记仅 adventure_runner 类变量 23 一件照登对账);跑 `python tools/run_smoke.py` 冒烟基线全绿读数落实现报告 -- [ ] grep 底账四件落实现报告:`oc\._`(settlement 七文件)、`_bp_store\._`(adventure_runner)、`slots\._`(save_manager)、`_fx_new_resource_types|_fx_bonus_delta`(grant)与 `\._resolver =`(config_db)——命中行号清单=T5 sweep 的改前底账 +- [ ] grep 底账五件落实现报告:`oc\._`(settlement 七文件)、`_bp_store\._`(adventure_runner)、`slots\._`(save_manager)、`_save\._`(slot_store——反向私取 21 处)、`_fx_new_resource_types|_fx_bonus_delta`(grant)与 `\._resolver =`(config_db)——命中行号清单=T5 sweep 的改前底账 **T2 settlement 七段解耦+搬家五方法**(估时 1.25 工作日;区间 1–1.5) 取用:T1 golden 基线。产出:处 1+处 2 清零——段类对编排器引用归零、五方法归位。 @@ -156,7 +156,7 @@ core 层(冒险/存档域) - [ ] 搬家五方法落位(宿主体逐字迁移、注解逐字保持): - damage_controller.gd:`_init` 加第五参 `facts_ref`(成员 `var facts: BattleFacts`,:49 构造体加行);新增 `func hero_atk() -> int`(体=battle_orchestrator.gd:70-71 逐字,`_facts`→`facts`);新增 `static func hits_of(hits: Array, kind: String) -> Array`(体=:489-494 逐字);`_emit_hero_damage_taken` 更名 `emit_hero_damage_taken` 公开化(体逐字;内部调用点 :449/:561 随改) - reward_grant.gd:新增 `func feat_yield_adjust(snap: Dictionary, positive: bool, pos_m: int, neg_m: int) -> Dictionary`(体=:452-461 逐字——reward_economy 为本件既有成员 :22) - - minesweeper_rules.gd:新增 `func harmful_variants(vids: Array) -> Array` 与 `func harmful_adjacent(cell: Vector2i) -> Array`(体=:466-473/:478-485 逐字——db 为本件构造参、current_board() 自有) + - minesweeper_rules.gd:新增 `func harmful_variants(vids: Array) -> Array` 与 `func harmful_adjacent(cell: Vector2i) -> Array`(体=:466-473/:478-485 逐字——db 为本件构造参、current_board() 自有;**:484 内部自呼 `_harmful_variants(board.variant_ids(n))` 随更名改 `harmful_variants(board.variant_ids(n))`,禁留旧名**) - battle_orchestrator.gd:五方法整段删除(:70-71/:452-461/:466-473/:478-485/:489-494);:282 `hero_atk_override: _hero_atk()` → `_damage.hero_atk()` - [ ] round_cycle.gd 重写:`_init(bundle: Dictionary)`——断言 7 必需键(facts/units/fx_host/db/action_economy/rng/emit_row_cb)后解包为同名成员;五段构造改 `XxxSegment.new(bundle)`;复制束写入 `"grant_seg": _grant_seg` 后构建 `BattleRefreshFlow.new(束副本)`;`settle_if_due(battle_result: String, ri: int)`(:35→参数、:40 删、段驱动用 ri);`roll_round_actions(ri: int)`(:67/:80 用 ri);新增 `func refresh_flow() -> BattleRefreshFlow`;全文 `oc.` 改址(映射表=`oc._facts`→`facts`、`oc._enemy_system`→`units`、`oc._emit_row`→`emit_row_cb.call`、`oc._fx_host`→`fx_host`、`oc.db`→`db`、`oc.action_economy`→`action_economy`、`oc.rng`→`rng`);头注「耦合边界」段改写(束注入+签名扩展+随编排器每战新建同灭语义不变) - [ ] grant_segment.gd 重写:`_init(bundle: Dictionary)` 断言 12 键解包 12 成员(第 4 节分配表);54 处改址——除上表映射外加:`oc._reward_economy`→`reward_economy`、`oc.minesweeper`→`minesweeper`、`oc._hero_atk()`→(无此调用)、`oc._feat_yield_adjust(...)`→`reward_grant.feat_yield_adjust(...)`(:99/:140)、`oc._harmful_variants`→`minesweeper.harmful_variants`(:87)、`oc._harmful_adjacent`→`minesweeper.harmful_adjacent`(:339)、`oc._hits_of`→`DamageController.hits_of`(:110/:115/:138/:356)、`oc.attune_param_sum("rap_transfer_mult")`→`int(attune_param_sum_cb.call("rap_transfer_mult"))`(:280)、`oc.perfect_sweep_earned()`→`bool(perfect_sweep_cb.call())`(:284)、`oc._damage._emit_hero_damage_taken(...)`→`damage.emit_hero_damage_taken(...)`(:197);:82-84 改 `var is_new_type := fx_host.mark_new_resource_type(ctype)`;:169-170 与 :378-379 改 `fx_host.add_bonus_delta(String(h.get("axis", "")), int(h.get("delta", 0)))`;头注改写 @@ -164,16 +164,17 @@ core 层(冒险/存档域) - [ ] combat_segment.gd 重写:`_init(bundle)` 断言 10 键解包;23 处改址(映射同上+`oc._fatal`→`fatal_cb.call`、`oc._status_effects`→`status_effects`、`oc._hero_atk()`→`damage.hero_atk()`);`oc._hits_of` 行随 3.1+3.2 批已删——复核以 grep 为准;头注改写 - [ ] aura_segment.gd(成员 `var emit_composition_cb: Callable`,:15-16 改 `emit_composition_cb.call("hero", ri)`/`("enemy", ri)`)、decay_segment.gd(成员 status_effects+emit_row_cb)、verdict_segment.gd(成员 units+四回调,:18/:20 `units.hero_unit()`/`units.query_alive("enemy")`、:22 `emit_snapshot_cb.call(verdict)`、:25/:29 `battle_over_cb.call(...)`、:32 `exit_distribution_cb.call()`)三件重写+头注改写 - [ ] battle_refresh_flow.gd 重写:去 static——`_init(bundle: Dictionary)` 断言 8 键(facts/db/action_economy/fx_host/reward_economy/minesweeper/install_cb/grant_seg)解包;`_effective_refresh_cost()` 无参实例方法(:15-20 体逐字,`oc.db`→`db`、`oc.fx_host().fx_emit`→`fx_host.fx_emit`);`can_refresh(battle_result: String) -> bool`(:24-28 体逐字,`oc.battle_result`→参数、`oc._facts.refresh_used`→`facts.refresh_used`);`execute(battle_result: String, round_index: int) -> bool`(:32-43 体逐字——`oc._facts.refresh_used += 1`→`facts.refresh_used += 1`、`oc._reward_economy.retire_mapping()`→`reward_economy.retire_mapping()`、`oc.minesweeper.retire_board(true)`→`minesweeper.retire_board(true)`、`oc._install_and_reset(true)`→`bool(install_cb.call(true))`、`oc._rounds._grant_seg.apply_board_refreshed(oc.round_index)`→`grant_seg.apply_board_refreshed(round_index)`);头注「调用路径」句改写(编排器单行转发形态不变) -- [ ] battle_orchestrator.gd 收口::598-599 `return BattleRefreshFlow.can_refresh(self)`→`return _rounds.refresh_flow().can_refresh(battle_result)`;:606-607 →`return _rounds.refresh_flow().execute(battle_result, round_index)`;:262 `roll_round_actions()`→`roll_round_actions(round_index)`;:447 `settle_if_due()`→`settle_if_due(battle_result, round_index)`;:593 →`roll_round_actions(round_index)`;`can_refresh`/`player_request_refresh`/`_on_round_end`/`begin_battle`/`_exit_distribution` 五处体注释同步 +- [ ] battle_orchestrator.gd 收口::598-599 `return BattleRefreshFlow.can_refresh(self)`→`return _rounds.refresh_flow().can_refresh(battle_result)`;:606-607 →`return _rounds.refresh_flow().execute(battle_result, round_index)`;:262 `roll_round_actions()`→`roll_round_actions(round_index)`;:447 `settle_if_due()`→`settle_if_due(battle_result, round_index)`;:593 →`roll_round_actions(round_index)`;`can_refresh`/`player_request_refresh`/`_on_round_end`/`begin_battle`/`_exit_distribution` 五处体注释同步+:280-281 注释(「`_hero_atk` 派生读=受理后不变量」句引用将删除的方法名)随 :282 改指一并改写 - [ ] 测试适配:settle_segments_test.gd :20-24 五段直构断言改束形态(以真实编排器协作件组装束逐段 `new(bundle)` 成功断言);:28-34 宿主回指断言 6 条改同一性断言(`oc._rounds._grant_seg.facts == oc._facts`、`oc._rounds._combat_seg.fx_host == oc.fx_host()` 等——同一性强度对应回指,削减弱化申报 1);adventure_feats_test.gd :671/:691/:727 `orch._hits_of(...)` → `DamageController.hits_of(...)`(削减弱化申报 2) - [ ] 孤立验证新增段 → 出红只跑红件最小单元 → 并入全套(回归措辞:里程碑卡出口跑一次全套闸;卡内修复只做出红最小单元的最窄确认);本卡出口=golden 快照绿+battle_settlement 套件全绿+冒烟全绿 -**T3 断点与存档公开面**(估时 0.5 工作日;区间 0.5–0.75) -取用:T1 底账。产出:处 3+处 4 清零。 +**T3 断点与存档公开面**(估时 0.625 工作日;区间 0.5–0.75) +取用:T1 底账。产出:处 3+处 4 双向清零。 -- [ ] breakpoint_store.gd 新增公开方法面(13 个,成员零增——类变量 15 贴顶):`func bind_save_manager(sm) -> void`、`func save_manager()`(读投影,可 null)、`func set_pending_next_level(v: bool) -> void`/`func pending_next_level() -> bool`、`func set_loadout_seeded(v: bool) -> void`/`func loadout_seeded() -> bool`、`func set_resume_bp(bp: Dictionary) -> void`/`func clear_resume_bp() -> void`/`func resume_bp() -> Dictionary`(返引用零拷贝——宿主读侧只读)、`func bp_read(key: String, bp: Dictionary, fallback: Variant = null) -> Variant`(=_bp_read 更名公开化,:160 内部调用点随改)、`func set_last_level_payload(payload: Dictionary) -> void`/`func last_level_payload() -> Dictionary`、`func set_last_treasure_cleared(v: int) -> void`/`func last_treasure_cleared() -> int`(方法体一律一行转发自有成员,零逻辑增量) +- [ ] breakpoint_store.gd 新增公开方法面(13 个,成员零增——类变量 15 贴顶):`func bind_save_manager(sm: SaveManagerCore) -> void`、`func save_manager() -> Variant`(读投影,可 null)、`func set_pending_next_level(v: bool) -> void`/`func pending_next_level() -> bool`、`func set_loadout_seeded(v: bool) -> void`/`func loadout_seeded() -> bool`、`func set_resume_bp(bp: Dictionary) -> void`/`func clear_resume_bp() -> void`/`func resume_bp() -> Dictionary`(返引用零拷贝——宿主读侧只读)、`func bp_read(key: String, bp: Dictionary, fallback: Variant = null) -> Variant`(=_bp_read 更名公开化,:160 内部调用点随改)、`func set_last_level_payload(payload: Dictionary) -> void`/`func last_level_payload() -> Dictionary`、`func set_last_treasure_cleared(v: int) -> void`/`func last_treasure_cleared() -> int`(方法体一律一行转发自有成员,零逻辑增量) - [ ] adventure_runner.gd 37 处改址(逐处)::107/:157/:180/:185/:241/:438 → `set_pending_next_level(...)`;:235 → `pending_next_level()`;:115/:191/:201 → `set_loadout_seeded(false)`;:300-301 → `loadout_seeded()`/`set_loadout_seeded(true)`;:189 → `set_resume_bp(bp.duplicate(true))`;:388 → `clear_resume_bp()`;:302/:376/:377/:378 → `resume_bp()`(读侧零拷贝语义不变);:168/:302/:377/:378/:412 `_bp_read` → `bp_read`;:220 → `bind_save_manager(sm)`;:325-326 → `var sm = _bp_store.save_manager()` 后 `if sm != null: first = not sm.meta_state.career_state()...`;:421 → `set_last_level_payload(payload.duplicate(true))`;:464/:467-468 → `last_level_payload()`;:430 → `set_last_treasure_cleared(...)`;:456 → `last_treasure_cleared()`;:474-476 → `var sm = _bp_store.save_manager()` 后 `sm.clear_breakpoint()`/`sm.write_to_disk()`;:37 头注自述句核改(「宿主读写经件」落实后注释与实态一致) -- [ ] slot_store.gd:新增 `func active_path() -> String: return _path`(读投影——has_write_target :53 同族);`_migrate_legacy_save` 更名 `migrate_legacy_save` 公开化(:150 体逐字;禁留旧名壳) +- [ ] slot_store.gd:新增 `func active_path() -> String: return _path`(读投影——has_write_target :53 同族);`_migrate_legacy_save` 更名 `migrate_legacy_save` 公开化(:150 体逐字;禁留旧名壳);**反向私取 21 处改址**(第 3.1 节处 4 清单):`_save._read_only` 写 4 处(:26/:38/:69/:91)→ `_save.set_read_only(false)`、读 2 处(:65/:87)→ `var prev_ro: bool = _save.read_only()`、恢复写 2 处(:74/:96)→ `_save.set_read_only(prev_ro)`;`_save._reset_to_default` ×5(:28/:39/:70/:92/:119)→ `_save.reset_to_default()`;`_save._data` 读 2 处(:66/:88)→ `var prev_data = _save.data_snapshot()`、恢复写 2 处(:75/:97)→ `_save.restore_data(prev_data)`(引用零拷贝语义不变——snapshot 返 `_data` 本引用);`_save._peek_summary_at` ×2(:129/:134)→ `_save.peek_summary_at(...)`;`_save._rename_overwrite` ×2(:159/:162)→ `_save.rename_overwrite(...)` +- [ ] save_manager.gd 新增公开方法面承接 SlotStore 反向私取(类变量零增;公开 7→14):`func set_read_only(v: bool) -> void`/`func read_only() -> bool`(体一行转发 `_read_only`)、`func reset_to_default() -> void`(体=:279 逐字公开化——件内调用点零改,同名);`func data_snapshot() -> Dictionary[String, Variant]: return _data`/`func restore_data(data: Dictionary[String, Variant]) -> void: _data = data`(零拷贝——还原引用);`_peek_summary_at` 更名 `peek_summary_at` 公开化(:217 体逐字;**件内调用点复核**——slot_store :129/:134 为外部消费,件内若另有调用随改);`_rename_overwrite` 更名 `rename_overwrite` 公开化(:317 体逐字;件内调用点 :118/:286 随改) - [ ] save_manager.gd 九行改址::51 → `slots.migrate_legacy_save(...)`;:66/:69/:105/:111/:118/:119/:285/:286 `slots._path` → `slots.active_path()`(:118-119 两处同名调用间 `_path` 无变更窗口——单线程同步段,逐位等价) **T4 效果宿主累积面与配置挂载面**(估时 0.375 工作日;区间 0.25–0.5) @@ -182,6 +183,7 @@ core 层(冒险/存档域) - [ ] 复核 T2 步骤中 battle_fx_host.gd 两方法与 grant_segment.gd 四处改址已落(T2 内联实装——本卡不重复列);孤立验证:grant_segment 相关套件(seal_polarity/round_flow)出红最小单元 - [ ] board_gen_table.gd / enemy_table.gd / difficulty_table.gd 各新增 `func bind_resolver(resolver: ConfigDbResolver) -> void`(体一行 `_resolver = resolver`;三件注解同型) - [ ] config_db.gd:157-159 三行改 `combat.board_gen.bind_resolver(_resolver)` / `combat.enemy.bind_resolver(_resolver)` / `run.difficulty.bind_resolver(_resolver)`(_assign_loaded 装配序零变化) +- [ ] **三 schema 解析冒烟(类型环验证义务)**:bind_resolver 引入 schema→ConfigDbResolver 参数类型注解,与 resolver 既有反向引用(config_db_resolver.gd:41/:61 引 EnemyTable.ROW_KINDS/band_of——:3-8 头注「类型环断根」先例)构成类型引用环——孤立验证必含 config_db_resolver_test 全套当轮真实跑(三 schema 经 `load()` 实例化+resolver 注入+resolve_row/resolve_rowset/resolve_modifiers 真实解析,类型环若引入解析失败当轮即炸);出红即 L3 停卡(禁改走 type-hint: ignore 通道——保 schema 类型注解完整) **T5 结构性扫描与批收口**(估时 0.375 工作日;区间 0.25–0.5) 取用:全部前卡。产出:五处结构性恒零证据+批收口两件。 @@ -190,7 +192,7 @@ core 层(冒险/存档域) ①七段文件集(settlement/ 七 .gd)逐件:文件存在且非空+含对应 `class_name` 正锚+`\boc\b` 全文零命中〔封装5.1 V2〕 ②battle_orchestrator.gd:非空+`func _hero_atk|func _feat_yield_adjust|func _harmful_variants|func _harmful_adjacent|func _hits_of` 零命中(五方法零残留)〔封装5.1 V3〕 ③adventure_runner.gd:非空+`_bp_store\._` 零命中+`_bp_store.bp_read(` 正锚(新面在用)〔封装5.1 V4〕 - ④save_manager.gd:非空+`slots\._` 零命中+`slots.active_path()` 正锚〔封装5.1 V5〕 + ④save_manager.gd:非空+`slots\._` 零命中+`slots.active_path()` 正锚;slot_store.gd:非空+`_save\._` 零命中+`_save\.(set_read_only|read_only|reset_to_default|data_snapshot|restore_data|peek_summary_at|rename_overwrite)` 正锚〔封装5.1 V5〕 ⑤grant_segment.gd:非空+`_fx_new_resource_types|_fx_bonus_delta` 零命中+`mark_new_resource_type(` 正锚〔封装5.1 V6〕 ⑥config_db.gd:非空+`\._resolver\s*=` 零命中+`bind_resolver(_resolver)` 正锚〔封装5.1 V7〕 - [ ] run_all.gd manifest 追加 2 行:settlement_wiring_snapshot_test(expect 0,注记「R1 同种子逐项 golden 对拍主证〔封装5.1〕」)+encapsulation_sweep_test(expect 0,注记「R1–R6 结构性零命中扫描〔封装5.1〕」) @@ -200,8 +202,8 @@ core 层(冒险/存档域) ### 估时汇总 -T1 0.25|T2 1.25|T3 0.5|T4 0.375|T5 0.375。 -区间合计 2.25–3.75 工作日;**精确汇总 2.75 工作日**(切分预案:若 T2 超 1.5 工日,把 T3 切出为独立半日卡顺延,其余不动;合计超 3 工作日=超卡面估时域,须用户确认后方可续批)。 +T1 0.25|T2 1.25|T3 0.625|T4 0.375|T5 0.375。 +区间合计 2.25–3.75 工作日;**精确汇总 2.875 工作日**(切分预案:若 T2 超 1.5 工日,把 T3 切出为独立半日卡顺延,其余不动;合计超 3 工作日=超卡面估时域,须用户确认后方可续批)。 ## 8. 验证闸(改动—验收对照表) @@ -213,7 +215,7 @@ T1 0.25|T2 1.25|T3 0.5|T4 0.375|T5 0.375。 | R2 搬家五方法归位 | damage_controller +hero_atk/hits_of/emit_hero_damage_taken 公开化+facts 成员;reward_grant +feat_yield_adjust;minesweeper_rules +harmful_variants/harmful_adjacent;编排器五方法删除+:282 改指 | settlement_wiring_snapshot_test〔封装5.1 V1〕(五方法消费路径全在行流内——主角攻击 base_value/奖励乘区/terrain_kind 事实/奥术矢开单);roll_multiplier_test.gd:_smoke_hero_atk_derived 既有回归;adventure_feats_test hits_of 面回归;encapsulation_sweep_test 编排器五方法定义零命中〔封装5.1 V3〕 | 单元 | `begin_battle()`(enc hero_atk override→spawn→攻击单)/授予段真实结算链 | 攻击单基值随 enc override 走(派生读贯通);行流逐位同;五方法宿主定义唯一(编排器零残留) | 既有:伤害公式与掷点乘区 | | R3 grant→BattleFxHost 累积方法 | battle_fx_host +mark_new_resource_type/+add_bonus_delta;grant :82-84/:169-170/:378-379 改址 | seal_polarity_test/round_flow_skill_pool_test 既有全套回归(血税 bonus_delta 与地质学家 new_resource_type 两订阅行行为面);encapsulation_sweep_test grant 私键零命中+正锚〔封装5.1 V6〕 | 单元 | 授予段真实结算链(mine_hit/seal_hit fx 发射→施加面) | bonus_delta 轴累积值与 new_resource_type 首见判定逐位同;grant 源零私键直写 | 既有:封印与极性路由/不可逆 | | R4 adventure_runner→BreakpointStore | breakpoint_store +13 公开方法面(_bp_read 更名 bp_read);adventure_runner 37 处改址 | save_rng_roundtrip_test.gd:_test_old_version_save_migrates_and_resumes+:_test_disk_roundtrip_preserves_breakpoint 既有回归(断点组装/回放/续玩全链真实入口);encapsulation_sweep_test `_bp_store\._` 零命中〔封装5.1 V4〕 | 单元+集成 | `AdventureRunner.resume_adventure()`/`start_adventure()`→`write_to_disk()`/`load_from_disk()` | 断点续玩逐位同(27 键冻结);adventure_runner 源零 `_bp_store._` 直读写 | 既有:旧档迁移链与断点续玩零跳号(集成) | -| R5 save_manager→SlotStore | slot_store +active_path/_migrate 更名公开化;save_manager 九行改址 | save_manager_domain_test.gd:_smoke_save+save_slot_isolation_test 既有回归;encapsulation_sweep_test `slots\._` 零命中〔封装5.1 V5〕 | 单元 | `SaveManagerCore.write_to_disk()`/`load_from_disk()`/`_ready()` 迁移口 | 写盘/读回/迁移路径逐位同(tmp+rename 原子序不变);save_manager 源零 `slots._` | 既有:存档写盘⇄读回往返保真 | +| R5 save_manager↔SlotStore 双向公开面 | save_manager→SlotStore=slot_store +active_path/_migrate 更名公开化+save_manager 九行改址;SlotStore→SaveManagerCore=save_manager +5 公开方法/2 更名公开化+slot_store 21 处改址 | save_manager_domain_test.gd:_smoke_save+save_slot_isolation_test 既有回归;encapsulation_sweep_test `slots\._` 与 `_save\._` 双向零命中+双正锚〔封装5.1 V5〕 | 单元 | `SaveManagerCore.write_to_disk()`/`load_from_disk()`/`_ready()` 迁移口/`SlotStore.activate_slot()`(三态恢复路径——read_only/data 快照还原)/`peek_slot_summary()`(窥视委托) | 写盘/读回/迁移/激活-恢复/窥视路径逐位同(tmp+rename 原子序、零拷贝还原语义不变);save_manager 源零 `slots._`+slot_store 源零 `_save._` | 既有:存档写盘⇄读回往返保真 | | R6 config_db→三表挂载 | 三 schema +bind_resolver;config_db :157-159 改址 | config_db_resolver_test.gd 既有全套回归(_test_rowset_order_preserved/_test_row_kind_routing/_test_difficulty_clamp——resolver 注入后解析面逐位同);encapsulation_sweep_test `\._resolver =` 零命中+正锚〔封装5.1 V7〕 | 单元 | `ConfigDB.load_tables()`(装配段)→`ConfigDbResolver.resolve_*()` | 行集解析/难度 clamp 逐位同;config_db 源零 `_resolver` 直写 | 既有:行集寻址、行序保序与难度乘数 clamp | **零行为改动面的证据义务**:本卡全部六行均为非行为改动(零行为变更批)——不设「行为改动」行;每行的零变更证明=T1 golden 同种子逐项比对(改前固化、改后全程绿)+既有套件零转红+结构性 sweep 恒零。能力行全部「既有」、零新增——判断依据:本批零行为变更=玩家可观测能力面零变化,无新能力可登记;受影响存量行的真实入口与代表用例名零变化(settle_segments_test/adventure_feats_test 文件名与其在册引用不变),故能力清单零编辑(批末核对义务在 T5)。 @@ -260,6 +262,7 @@ T1 0.25|T2 1.25|T3 0.5|T4 0.375|T5 0.375。 - `MinesweeperRules.harmful_variants`/`harmful_adjacent`——改名迁移;db 为构造参(:44 既有)。grep 唯一。 - `BattleFxHost.mark_new_resource_type`/`add_bonus_delta`——新方法旧账面(成员零增);grep 同名零命中,命名与既有 apply_ac_bonus/counter_add 动词族同型。 - `SlotStore.active_path`——grep 全库零同名;has_write_target 同族读投影。 +- SaveManagerCore 五公开面(承接 slot_store 反向私取)——`set_read_only`/`read_only`/`reset_to_default`/`data_snapshot`/`restore_data` grep 作方法名全库零第二处(现仅为成员名或私有方法);`peek_summary_at`/`rename_overwrite` 为私有方法更名公开化非并存(禁别名,第 13 节适用);`reset_to_default` 件内既有调用点同名零改。 - `BreakpointStore` 13 方法——grep `pending_next_level|loadout_seeded|resume_bp|last_level_payload|last_treasure_cleared|bp_read|bind_save_manager` 作为**方法名**全库零命中(现仅为成员名);成员到方法一一对应,无第二落点。 - 三 schema `bind_resolver`——grep 零同名;参数类型 ConfigDbResolver 与 config_db.gd:43 既有协作类同一实例。 - `RoundCycle.refresh_flow`——grep 零同名;读出口与 stats()/wallet() 组件出口先例同型(adventure_runner.gd:60-82)。 @@ -277,9 +280,9 @@ T1 0.25|T2 1.25|T3 0.5|T4 0.375|T5 0.375。 新增 .gd 文件仅 2 个测试件(SceneTree 测试脚本,全类型标注、零公开生产面——接口块预算余量充足)。生产代码全部落既有件,按「存量触面一查」逐件对账(S13 默认阈值:公开方法 ≤20/类变量 ≤15/分支 ≤8/返回 ≤6): - **贴顶四件(禁再增成员,T1 读数锁定)**:battle_orchestrator.gd 15(本批成员零净增——五方法删除不涉成员);round_cycle.gd 8→15(束解包 7+_refresh_flow 1+既有 7——贴顶,头注记「贴顶禁再增」);battle_fx_host.gd 15(零增,方法-only);breakpoint_store.gd 15(零增,方法-only)。 -- **类变量净增件**:grant_segment 3→12、combat_segment 3→10、verdict 1→5、aura 1→1、decay 0→2(aura/decay 按 1/2 计——现各持 oc 一员)、battle_refresh_flow 0→8、damage_controller 12→13——全部 ≤15。 -- **公开方法净增件**:minesweeper_rules 18→**20 贴顶**(+2)、damage_controller 10→13(+hero_atk/hits_of/emit_hero_damage_taken 公开化)、reward_grant 9→10、battle_fx_host 16→18、slot_store 10→11、breakpoint_store 5→18、RoundCycle 3→4、三 schema 各 +1——全部 ≤20。 -- **迁移函数对账**:搬家五方法+`_migrate_legacy_save`+`_bp_read`+`_emit_hero_damage_taken` 逐个查 `tools/gdstyle_baseline.txt` 源键——基线无此 8 键(默认阈值内),迁移即原体;若 T1 读数发现任一源函数 branches/returns 超默认登记值,迁移即拆函数(拆分不改语义,不算迎合机检——与第 13 节区分)。 +- **类变量净增件**:grant_segment 3→12、combat_segment 3→10、verdict 1→5、aura 1→1、decay 1→2(两件现各持 oc 一员——aura 换单回调成员 1→1、decay 换两成员 1→2)、battle_refresh_flow 0→8、damage_controller 12→13——全部 ≤15。 +- **公开方法净增件**:minesweeper_rules 18→**20 贴顶**(+2)、damage_controller 9→12(+hero_atk/hits_of+emit_hero_damage_taken 公开化——2026-11-03 终审实核现值 9)、reward_grant 9→10、battle_fx_host 16→18、slot_store 10→11、breakpoint_store 5→18、save_manager 7→14(+5 承接方法+peek_summary_at/rename_overwrite 两更名公开化)、RoundCycle 3→4、三 schema 各 +1——全部 ≤20。 +- **迁移函数对账**:搬家五方法+`_migrate_legacy_save`+`_bp_read`+`_emit_hero_damage_taken`+`_peek_summary_at`+`_rename_overwrite` 逐个查 `tools/gdstyle_baseline.txt` 源键——基线无此 10 键(默认阈值内),迁移即原体;若 T1 读数发现任一源函数 branches/returns 超默认登记值,迁移即拆函数(拆分不改语义,不算迎合机检——与第 13 节区分)。 - **存量触面 S13 预期**:本卡触件 15 件(第 3.2 节清单)S13 键较 T1 现场基线**只降不升**(净删为主:五方法约 45 行迁出、107 处 oc._ 改址不增行数;净增面=两累积方法+13 bp 方法面+束解包成员行);adventure_runner 既有登记键(类变量 23)照登对账零变化。降不达即检查是否夹带超预算成员,L3 ③兜底。 - **指标例外申报**:无(零新件、零超默认阈值新增面;若实现中发现例外,走本卡异常分级 L3 ③停卡,禁就地豁免)。 From 63fc3e74c4b93e31803beaceb8b02b958658a818 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 3 Nov 2026 07:02:25 +0800 Subject: [PATCH 06/19] =?UTF-8?q?=E6=96=87=E6=A1=A3=E8=AE=BE=E8=AE=A1(?= =?UTF-8?q?=E6=9E=B6=E6=9E=84=E5=AE=A1=E6=9F=A55.2=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E6=BC=82=E7=A7=BB=E8=AE=A2=E6=AD=A3=C2=B7=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=8E=88=E6=9D=83=E7=9B=B4=E6=94=B9):=20=E5=9B=9B=E9=A1=B9?= =?UTF-8?q?=E6=BC=82=E7=A7=BB=E5=BD=92=E7=9C=9F=E2=80=94=E2=80=94=E2=91=A0?= =?UTF-8?q?architecture.md=E5=A4=B1=E6=95=88HeroLedger=E8=A1=8C=E5=88=A0?= =?UTF-8?q?=E9=99=A4,=E4=B8=BB=E8=A7=92=E8=B4=A6=E4=B8=89=E4=BB=B6(HeroSta?= =?UTF-8?q?ts/GainJournal/GpWallet)=E4=B8=8E=E5=88=B7=E6=96=B0=E8=B4=A6?= =?UTF-8?q?=E4=BB=B6RefreshBank=E5=9B=9B=E8=A1=8C=E6=8C=89=E7=9B=98?= =?UTF-8?q?=E4=B8=8A=E5=AE=9E=E4=BB=B6=E8=A1=A5=E7=99=BB=E8=AE=B0(?= =?UTF-8?q?=E9=99=84CurioStop=E8=A1=8C=E8=90=BD=E8=B4=A6=E6=8C=87=E7=A7=B0?= =?UTF-8?q?=E9=9A=8F=E6=8B=86=E4=BB=B6=E6=94=B9=E6=8C=87HeroStats+GainJour?= =?UTF-8?q?nal+RefreshBank=E3=80=81RunLedger=E9=80=80=E5=BD=B9=E5=8F=99?= =?UTF-8?q?=E8=BF=B0=E4=B8=A4=E5=A4=84HeroLedger=E6=8C=87=E7=A7=B0?= =?UTF-8?q?=E6=94=B9=E7=8E=B0=E8=A1=8C=E4=BB=B6=E5=90=8D)=E2=91=A1?= =?UTF-8?q?=E6=8B=86=E4=BB=B6=E5=AE=9A=E7=A8=BF=E8=8A=82=E5=86=BB=E7=BB=93?= =?UTF-8?q?=E8=AE=A1=E6=95=B0=E6=91=98=E9=99=A4(1313=E8=A1=8C/50=E6=88=90?= =?UTF-8?q?=E5=91=98=E2=80=94=E2=80=94=E6=B4=BB=E4=BD=93=E6=B8=85=E5=8D=95?= =?UTF-8?q?=E4=B8=8D=E5=86=BB=E7=BB=93=E8=AE=A1=E6=95=B0,=E5=8E=86?= =?UTF-8?q?=E5=8F=B2=E8=AF=BB=E6=95=B0=E6=9F=A5git)=E2=91=A2EC8=E7=83=AD?= =?UTF-8?q?=E9=87=8D=E8=BD=BD=E6=AD=BB=E9=93=BE=E8=A7=84=E6=A0=BC=E9=80=80?= =?UTF-8?q?=E5=BD=B9(=E7=94=A8=E6=88=B7=E6=80=BB=E5=88=A4=E6=8D=AE3?= =?UTF-8?q?=E6=AD=BB=E4=BB=A3=E7=A0=81=E4=B8=8D=E4=BF=9D=E7=95=99=C2=B7202?= =?UTF-8?q?6-11-02=E5=85=88=E4=BE=8B,=E4=BE=9D2026-11-03=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E6=8E=88=E6=9D=83):=E6=95=B0=E6=8D=AE=E9=85=8D=E7=BD=AE.md=20v?= =?UTF-8?q?1.3=E5=85=AB=E5=A4=84=E6=91=98=E9=99=A4(=E7=AE=A1=E7=BA=BF?= =?UTF-8?q?=E8=A1=8C/=E7=83=AD=E9=87=8D=E8=BD=BD=E6=AE=B5=E2=80=94?= =?UTF-8?q?=E2=80=94=E8=BD=AF=E7=9D=80=E9=99=86=E4=BE=8B=E5=A4=96=E6=B6=88?= =?UTF-8?q?=E5=A4=B1fail-fast=E5=85=A8=E5=9F=9F=E7=BB=9F=E4=B8=80/?= =?UTF-8?q?=E4=B8=8B=E6=B8=B8=E4=B8=A4=E8=A1=8C/HUD=E8=A1=8C=E5=88=A0?= =?UTF-8?q?=E9=99=A4/=E9=AA=8C=E6=94=B6#6=E5=88=A0=E9=99=A4=E9=87=8D?= =?UTF-8?q?=E7=BC=96=E5=8F=B7/P2=E8=A1=8C=E5=88=A0=E9=99=A4/=E8=B0=83?= =?UTF-8?q?=E5=8F=82=E8=A1=A8=E7=83=AD=E9=87=8D=E8=BD=BD=E9=97=A8=E8=A1=8C?= =?UTF-8?q?=E5=88=A0=E9=99=A4/=E8=AE=A1=E6=95=B0=E5=99=A8=E7=BA=AA?= =?UTF-8?q?=E5=BE=8B=E5=8F=A5=E8=AE=A2=E6=AD=A3)+=E6=88=98=E6=96=97?= =?UTF-8?q?=E7=BB=93=E7=AE=97.md=20v1.7=E4=B8=A4=E5=A4=84(=E5=BC=80?= =?UTF-8?q?=E5=BC=A0=E5=BA=8F=E5=88=97=E5=8E=BB=E5=85=B3=E9=97=A8=E6=AD=A5?= =?UTF-8?q?/=E4=B8=8A=E6=B8=B8=E8=A1=8C)+=E6=A3=8B=E7=9B=98=E7=94=9F?= =?UTF-8?q?=E6=88=90.md=20v1.3=E4=B8=80=E5=A4=84(=E7=83=AD=E9=87=8D?= =?UTF-8?q?=E8=BD=BD=E4=BB=8E=E5=8F=A5=E5=88=A0)+architecture.md=E6=8A=97?= =?UTF-8?q?=E7=83=AD=E9=87=8D=E8=BD=BD=E5=8F=A5=E6=94=B9=E6=8E=88=E4=BA=88?= =?UTF-8?q?=E6=97=B6=E5=AE=9A=E6=A0=BC=E2=80=94=E2=80=94set=5Freload=5Fgat?= =?UTF-8?q?e/reload=E4=BB=A3=E7=A0=81=E9=9D=A2=E9=80=80=E5=BD=B9=E7=95=99?= =?UTF-8?q?=E5=BE=85P2=E5=8D=A1,architecture.md:88=E5=85=AC=E5=BC=80?= =?UTF-8?q?=E9=9D=A2=E7=99=BB=E8=AE=B0=E4=B8=8E:386-387=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E7=8E=B0=E6=80=81=E4=BF=9D=E7=95=99=E2=91=A3MetaProgression?= =?UTF-8?q?=E5=9F=BA=E7=A1=80=E5=B1=82=E8=A1=A5=E7=99=BB=E8=AE=B0=E8=A1=8C?= =?UTF-8?q?(=E5=9B=9BAutoload=E5=94=AF=E4=B8=80=E8=B7=A8Autoload=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E4=BB=B6,=E6=9E=84=E9=80=A0=E5=8F=8C=E5=BD=A2?= =?UTF-8?q?=E6=80=81+=E6=B3=A8=E5=86=8C=E9=A1=BA=E5=BA=8F=E5=8D=B3?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E5=BA=8F)=E2=80=94=E2=80=94=E6=9E=B6?= =?UTF-8?q?=E6=9E=84=E6=96=87=E6=A1=A3v1.32;=20=E6=96=87=E6=A1=A3=E5=9F=9F?= =?UTF-8?q?=E9=97=B8=E5=85=A8=E7=BB=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../engineering/architecture/architecture.md | 20 +++++++++++-------- design/gdd/systems/战斗循环/战斗结算.md | 6 +++--- design/gdd/systems/排雷循环/棋盘生成.md | 4 ++-- design/gdd/systems/表现与支撑/数据配置.md | 18 +++++++---------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/design/engineering/architecture/architecture.md b/design/engineering/architecture/architecture.md index 7aab90d8..e2ff7478 100644 --- a/design/engineering/architecture/architecture.md +++ b/design/engineering/architecture/architecture.md @@ -2,8 +2,8 @@ ## 文档状态 -- 版本:1.31 -- 最近更新:2026-11-02(迭代 49 批后收尾随动——轴戊两件与功能层四行换代已建件现状、ui_registry 行三域句柄分域换代;沿革查 git) +- 版本:1.32 +- 最近更新:2026-11-03(架构审查 5.2 文档漂移订正——主角账三件与刷新账件四行补登记替代失效的 HeroLedger 行、MetaProgression 基础层补登记行(四 Autoload 唯一跨 Autoload 依赖件)、拆件定稿节冻结计数摘除(活体清单不冻结计数)、CurioStop 行落账指称随拆件改指;沿革查 git) - 引擎:Godot 4.7.2-stable(GDScript 单语言;2026-09-07 锁定) - 评审模式:solo(`review-mode.txt`,2026-09-12 用户拍板——TD/LP 门禁按 solo 跳过,用户授权架构产出自主推进、迭代期回调) - 覆盖 GDD:现行全集(根索引=`design/gdd/02-系统清单.md`,文档树构成以根索引为准) @@ -88,6 +88,7 @@ | **ConfigDB**(autoload,D2) | 全部玩法数值表与表现层布局配置表(`data/tables/*.tres` + `data/schemas/*.gd`);加载/校验/override/诊断状态机。**行族访问器归位各 schema 表类(表管自己的行查询),本类只留加载/校验/override/诊断门面;表持有成员按域收进四张域容器 Resource(`config_domain_combat/run/crossrun/presentation.gd`——前三件迭代 41 已建件,第四件表现层布局域 2026-10-30 建件,类型化成员 7/7/5/1);三张 resolver 表(board_gen.resolve_row/enemy.resolve_rowset/difficulty.resolve_modifiers)经 `load_tables` 装配段注入各容器,resolver 文件与键零搬移**——红线不变:本类仍是唯一加载与持有单点,"经 ConfigDB 单点读取"=经其持有的表对象 | 类型化域容器属性(每域一张容器);公开面 8(push_diag/is_fatal/reset_diagnostics/diagnostics/diagnostics_count/load_tables/set_reload_gate/reload)、类变量 10 | 无(基础层顶点) | Resource/.tres 加载、autoload 生命周期——LOW | | **SlotStore**(`core/slot_store.gd`,D3 存档槽位域件,已建件——迭代 41 存量债批) | 存档三槽位文件域唯一所有者(自 save_manager 收编槽位族):槽位挂载与模板、激活与建删、槽位摘要窥视(peek 族);改名覆盖原语(_rename_overwrite)留 save_manager(IO 原语单点) | 槽位读写原语族+摘要投影(公开 10/类变量 4;SaveManager 与菜单消费方经 `save.slots.` 直连) | save_manager(注入路径与模板配置);FileAccess——LOW | | **MetaStateStore**(`core/meta_state_store.gd`,D3 存档内元进度数据件,已建件——迭代 41 存量债批) | 存档内元进度数据的读写唯一层(自 save_manager 收编 accessor 族:钥石/道具解锁/树节点与叉侧/锻造路线/同调/真视/计数器/摘要——数据读写原语,不含业务规则);save_manager 与 meta_progression 双 God Class 的共同病根=该数据域摊在两文件,本件即其归一 | 写口原语 13+只读投影 6(tree_state/forge_state/attune_state/career_state 四投影+keystone_balance/item_unlocked)=公开 19(add_keystone 私有 `_add_keystone`),零 _data 副本零缓存;MetaProgression 业务层与营地/锻造 UI 消费方经 `save.meta_state.` 直连(meta 的纯转发读方法已退役) | save_manager(序列化接线);FileAccess——LOW | +| **MetaProgression**(autoload,`core/meta_progression.gd`,D3 元进度业务层) | 元进度账本服务:钥石收束入账、营地消费定价与秘宝解锁判定的纯被动服务,零信号零外发;数据读写全经注入的 MetaStateStore(`save.meta_state.` 直连);hero_override() 现算不写表(全零=白板合法态——生效注入只走冒险开始参数面显式传参) | 写口族(天赋树购买/叉侧切换/锻造解锁与升级与选中/同调装配切换等)+解锁判定与读投影;**构造双形态**=autoload 装配走 `.new()` 零参+`_ready` 从 autoload 链取依赖(工程序 ConfigDB→RngService→SaveManager→MetaProgression,注册顺序即依赖序),单测/工具走 `.new(db, save)` 直构形态(不入树零 _ready)——**四个 Autoload 中唯一有跨 Autoload 依赖的件(ConfigDB/SaveManager)** | ConfigDB(定价与档位表值);SaveManager(存档访问器,经节点路径延迟取用) | autoload 生命周期——LOW | | **RngService**(autoload,D2) | master_seed、各流 scope 计数器(封闭流词表现值以 `RngServiceCore.PURPOSE_TAGS` 为准;增流走 P1 评审) | `set_master_seed()`(唯一调用方 C2);`open_stream(stream)` 有状态门面;`derive_at(stream, scope)` 纯函数;只读计数器 | ConfigDB(无) | 无——纯逻辑 | | **action_economy**(A3) | AP/RAP 账本、last_round_end、轮次相位机 {Idle, Active, Waiting}、结束仲裁;dig_paid 命中施加抽私有单点(_apply_dig_paid_hits——矿脉储能入池面) | 意图与通知布尔面:notify_round_start / request_dig / request_stop / request_refresh(收折后价入参——折价计算归 BattleRefreshFlow 单点)/ notify_settlement_done / notify_combat_end;预授权通道:grant_reserve_ap / finish_round_stop;ap/rap/phase 只读;实测类变量 10 | ConfigDB(ActionEconomyTable);EffectPort(效果端口件——发射经端口单点;2026-11-02 轴戊设计闭合、迭代 49 卡① 建件,effect_engine 直连退役);B1 回发 next_round_mode/battle_over | 无 | | **variation 定义**(A4) | VariationTable schema(现行 6 行:六 region——贫矿脉 global 行 2026-10-16 用户令屏蔽删行,global 型机制代码保留)与 F1 候选池门控谓词 | `variant_pool(level_index, board_type, node_type="")`(门控三维:unlock+board_types+节点身份——global 行仅 boss/elite 入池,缺省跳过零扰动);`global_variant_row(level_index, board_type, node_type)`(全局型单行决议访问器) | ConfigDB(VariationTable) | 无 | @@ -107,9 +108,12 @@ | **helper_items**(A5,切片已实装秘宝域) | HelperItemTable、探测显影语义 | (契约规范源:`../../gdd/systems/跨局循环/秘宝.md`——桥接位:A2 查询接口 + A4 counter_item_ids) | A2 / A4 / B4 | 无 | | **CurioDeck**(`core/curio_deck.gd`,A5 秘宝域令牌池件,迭代 37 自 AdventureRunner 拆出) | 三选一/商店共享池的持久多重集、抽签(候选抽取)、cap 库存与专长凭证三计数与判定唯一所有者——件只管池与判定,停点编排与兑付推进留冒险编排器 | `draw_candidates(channel)` 抽签;`consume_deck_token` / `consume_pool_purchase` 池消耗;`cap_ok` 上限判定;`feat_ticket_consider` 凭证判定;`stock_snapshot` / `pool_stock` 只读投影;商店购买消费经注入 Callable 链至 CurioStop 兑付单点(迭代 39 起转纯池——bind_handlers 反向回调已退役) | ConfigDB(秘宝令牌行集);注入 RngServiceCore(reward_pick 封闭流,禁自建随机) | 无(RefCounted 纯逻辑) | | **ShopSession**(`core/shop_session.gd`,商店会话件,迭代 37 自 LevelRunner 拆出) | 关卡商店双模式(legacy 固定三件加定价/pool 共享令牌池)的货架、定价、购买与刷新唯一宿主——账本/钱包/装配集归宿主 LevelRunner(共享引用经 `bind` 注入,出账直接落同一引用改写宿主账本);legacy 模式零 RNG 零池消费(off 对照承载) | 货架与定价只读面(`shop_products` / `shop_shelf` / `current_price` / `shop_refresh_cost`)+写入口(`buy_product` / `buy_pool_item` / `shop_refresh` / `player_request_refresh` / `open_pool`);外部调用面=调用方经宿主 LevelRunner 公开成员 `shop` 直连(调用直连不留委托壳,2026-10-26 Middle Man 裁定;迭代 42 拆除),直连消费的方法=`shop_products`/`current_price`/`purchased_tier`/`buy_product`/`player_request_refresh`/`set_shop_pool`/`pool_price`/`shop_shelf`/`shop_refresh_free_left`/`shop_refresh_cost`/`shop_refresh`/`spend_gp`/`buy_pool_item`/`is_shop_pool`/`shop_bp_shelf`/`shop_bp_visit_buys`(另白盒两入口仅测试侧:`_draw_shelf`/`_spend_discounted`);set_shop_pool 调用面=pool 注入经 LevelRunner 构造 ctx 供给(构造期内部直调,原委托块注释「AdventureRunner._start_current_level 唯一调用方」系陈旧表述、随壳删除作废),测试面直连 `shop.set_shop_pool` | ConfigDB(商店行集);注入 RngServiceCore;宿主钱包/账本引用;pool 模式令牌消耗与判定经注入 Callable 转 CurioDeck | 无 | -| **HeroLedger**(`core/hero_ledger.gd`,冒险域主角实体账,已实装(2026-10-27 迭代 39 拆件批)) | 冒险生命周期主角数值与获得记录唯一所有者:生命与 GP 钱包(gain/spend/clear 单写原语,钱包事件发射点归件)、锻造强化快照、调试百分比、攻击/甲类型轴快照、特性持有集(活引用注入——关内兑付当关生效)、本局钥石增量与逐杀明细、真视使用记录;获得记录三层结构=获得记录列表(三选一件/商店购买/战末奖励各一条)→属性增益明细(带来源指回)→四轴汇总(由明细推导);生效上限与回血封顶公式单点归件 | 构造注入;单写原语族+只读投影;断点自交片段(账本键+获得日记键) | ConfigDB(表值读取);由 AdventureRunner 冒险开始创建、注入 CurioStop/level_runner/ShopSession/战斗 encounter | 无(RefCounted 纯逻辑) | +| **HeroStats**(`core/hero_stats.gd`,主角数值账件,已实装(2026-10-27 迭代 39 拆件批——原 HeroLedger 登记行拆件替代)) | 冒险生命周期主角数值域唯一所有者:生命账与特性持有集(活引用注入——关内兑付当关生效)、锻造强化快照、调试百分比通道、攻击/甲类型轴快照、生效上限/攻击/护甲公式与回血封顶公式单点、续玩生命钳制收口;生效公式经注入 GainJournal 只读引用取加算区汇总(无反向引用不成环) | 构造注入;单写原语族+只读投影;断点自交片段(账本键) | ConfigDB(表值读取);注入 GainJournal(只读);由 AdventureRunner 冒险开始创建、注入战斗 encounter | 无(RefCounted 纯逻辑) | +| **GainJournal**(`core/gain_journal.gd`,加算日记件,已实装(2026-10-27 迭代 39 拆件批)) | 统一冒险加算区与获得记录唯一所有者:获得记录三层结构=记录列表(三选一件/商店购买/战末奖励各一条)→属性增益明细(带来源指回)→四轴汇总(由明细同步维护);三写通道统一走 gain_bonus 单写原语(source_class=curio_pick/shop_product/battle_export);本局钥石增量与逐杀明细、真视使用记录、商店已购档数记账同域 | gain_bonus 单写原语;记录与汇总只读投影;断点自交片段(获得日记键) | 由 AdventureRunner 冒险开始创建、注入 CurioStop/level_runner/ShopSession/战斗 encounter(战末 bonus 四轴经 gain_bonus 汇入) | 无(RefCounted 纯逻辑) | +| **GpWallet**(`core/gp_wallet.gd`,GP 钱包件,已实装(2026-10-27 迭代 39 拆件批)) | 冒险局内货币唯一所有者(LevelRunner 与 ShopSession 读写全指此单点;冒险开始=0、收束清零,不入存档不入摘要) | gain/spend/clear 单写原语 | 由 AdventureRunner 冒险开始创建;宿主与商店经注入引用读写 | 无(RefCounted 纯逻辑) | +| **RefreshBank**(`core/refresh_bank.gd`,刷新账件,已实装(2026-10-27 迭代 39 拆件批)) | 三选一刷新三源账唯一所有者:X 刷新件每碰三选一重给(优先消耗不结转)/Y 营地升级行冒险周期池(用完即无)/刷新券存量账(冒险级跨停点持久)+GP 付费刷计数与报价公式;零停点态依赖(免费/付费支出的编排归 CurioStop,本件只记账) | 支出与余量原语+报价公式;断点自交片段(refresh_stock/attune_refresh_y 两键,Y 缺键回退参数面) | ConfigDB(刷新件与营地升级行表值);注入 CurioStop 支出路径 | 无(RefCounted 纯逻辑) | | **AttuneLoadout**(`core/attune_loadout.gd`,同调配装件,已实装(2026-10-27 迭代 39 拆件批)) | 装备中的秘宝件对象集唯一所有者(每件内含充能单位与重置周期);同调充能的物化行为唯一事实源——种行/补行改写时同步(RunLedger 充能字典轨与差额对账函数退役);旧档 aux_items 同调行迁移归件 | 构造注入;充能查询/消耗/按周期重置原语;断点自交片段(attunement_charges 键,键名与策略不变) | ConfigDB(秘宝行集);TreasureItems(同调行投放面);注入战斗使用路径 | 无 | -| **CurioStop**(`core/curio_stop.gd`,三选一停点件,已实装(2026-10-27 迭代 39 拆件批)) | 三选一停点编排唯一所有者(架构原则 9 本域承载):停点三态(关卡完成三选一在途/已兑付待推进/奖励节点三选一在途)、刷新三源账(刷新件 X/营地池 Y/刷新券存量/付费刷新计数)、兑付方法族(pick/refresh/redeem/skip)、凭证出箱(RAP/时沙待注入);三选一信号面自带;零自动推进停点语义承载 | 对外=开停点/刷新/兑付/放行谓词/交断点片段五组入口+信号面(curio_choice_presented/curio_resolved);由 AdventureRunner 关卡完成受理时调用 | ConfigDB;注入 CurioDeck(抽签/摘牌)与 HeroLedger(落账);随机只经 CurioDeck 的 reward_pick 封闭流 | 无 | +| **CurioStop**(`core/curio_stop.gd`,三选一停点件,已实装(2026-10-27 迭代 39 拆件批)) | 三选一停点编排唯一所有者(架构原则 9 本域承载):停点三态(关卡完成三选一在途/已兑付待推进/奖励节点三选一在途)、刷新编排(三源账面归 RefreshBank 件、查停点态→支出→重抽重发编排留本件)、兑付方法族(pick/refresh/redeem/skip)、凭证出箱(RAP/时沙待注入);三选一信号面自带;零自动推进停点语义承载 | 对外=开停点/刷新/兑付/放行谓词/交断点片段五组入口+信号面(curio_choice_presented/curio_resolved);由 AdventureRunner 关卡完成受理时调用 | ConfigDB;注入 CurioDeck(抽签/摘牌)、HeroStats 与 GainJournal(兑付落账单写原语)、RefreshBank(刷新支出);随机只经 CurioDeck 的 reward_pick 封闭流 | 无 | | **breakpoint_store**(`core/breakpoint_store.gd`,冒险域·断点组装与回放件,已建件——迭代 45) | 存档断点组装与回放唯一承载(自 adventure_runner 收编 6 成员+函数族):断点快照拼盘、回放回填、读侧策略分发;`BREAKPOINT_FIELDS` 27 键登记单源随件(键名/策略标签/键序冻结) | 构造=引用束注入(九引用束成员解包为原名成员——保迁移函数体逐字);`resume_adventure` 留宿主(壳+宿主侧回填语句——R2 所有权缝分家);断点键面零变化;实测类变量 15(贴顶禁再增) | adventure_runner(宿主);注入主角账三件与 curio/stop/bank/loadout 引用 | 无(RefCounted 纯逻辑) | ### 功能层 @@ -136,7 +140,7 @@ ### 战斗编排域拆件定稿(2026-10-26 用户裁写入——gdstyle 存量债波 1 设计闭合;同日独立审查(grilling+godot-master 双子代理)阻断 8 条去重 6 组全折入本节,v1.18;2026-10-28 迭代 40 实现批合回(合并提交 514457d1),本节为现状登记) -- **轴甲两件**:battle_orchestrator(1313 行/50 成员,S13 全库单文件最大户)按变化原因拆出 BattleFxHost(效果引擎宿主域)与 RewardGrant(奖励授予域)两协作件;宿主保留架构在册职责全部——战斗状态机与生命周期、轮 facts 缓冲(_facts_reveals/seals/path)、A2 三事件订阅、结算五段驱动、attune 族原位、行发射基建(_emit_row/_assert_row_source/_fatal)、呈现投影(presentation/diagnostic_snapshot 唯一出口不变)、刷新面、nest_preview_count(巢穴预告读数口——外部直读面 main.gd 与 treasure_effects_test 随批点名冻结)。拆件动机与残留债口径见待办清单「gdstyle 存量债全量清偿」条目。 +- **轴甲两件**:battle_orchestrator(拆件时 S13 全库单文件最大户——行数与成员数为历史读数,冻结计数不登记,查 git)按变化原因拆出 BattleFxHost(效果引擎宿主域)与 RewardGrant(奖励授予域)两协作件;宿主保留架构在册职责全部——战斗状态机与生命周期、轮 facts 缓冲(_facts_reveals/seals/path)、A2 三事件订阅、结算五段驱动、attune 族原位、行发射基建(_emit_row/_assert_row_source/_fatal)、呈现投影(presentation/diagnostic_snapshot 唯一出口不变)、刷新面、nest_preview_count(巢穴预告读数口——外部直读面 main.gd 与 treasure_effects_test 随批点名冻结)。拆件动机与残留债口径见待办清单「gdstyle 存量债全量清偿」条目。 - **轴丙一件(2026-10-29 尾波清偿批设计闭合——实现批建件)**:battle_orchestrator 装板域六函数(`_install_new_board`/`_resolve_global_variant`/`_place_variants`/`_place_variants_apply`/`_variants_fringe`/`_adjacent_to_packs`,约 140 行;全仓仅宿主三调用点——begin_battle/中途刷新受理/player_request_refresh,实查零外部调用)按变化原因拆出 BoardInstaller,职责语句「棋盘安装与变异布置域」(生成→全局变异决议→装板受理→资源摇号→变异布置;单一变化原因=棋盘设置顺序与变异布置算法)。形态两修正(实测裁,与初案「逐字搬运」之差):①宿主复位块不随件——`_install_new_board` 体内五处计数清零、板序推进、board_changed 发射与秘宝叠加层退役留宿主薄壳 `_install_and_reset`,三调用点改调薄壳、时序逐字;②`_board_generator` 全文件仅装板族使用——实例随件自建自接线(fatal 经注入 Callable),宿主成员退役(类变量 38→37,禁无效成员义务)。encounter(23 处跨宿主)与 _reward_economy(18 处)确认留宿主、经引用束注入。文件长键(1035/1000)随本件迁出归绿;attune 族与 begin_battle 受理段序禁动不变。 - **轴丁两件(2026-10-29 零豁免裁设计闭合——实现批建件)**:RoundCycle(轮循环驱动件)与 BattleFacts(战斗事实件)见功能层表两行——宿主 38(轴丙落地后 37)→15,S13 豁免第三条注销;宿主保留面改登记为「战斗状态机与生命周期、行发射基建(_emit_row/_assert_row_source/_fatal)、呈现投影(两快照出口签名不变)、刷新面、nest_preview_count」;attune 族处置由下一条改判;treasure_inventory 注入改址追认——原「外部赋值路径零改址」句失效,level_runner 经 RewardGrant 出口直注;成员级对账以需求卡片为卡内契约(开工 T0 复核)。 - **轴戊两件(2026-11-02 用户裁甲案设计闭合——已建件,迭代 49 卡① 合回,git 提交 848723b5)**:①**效果端口件 EffectPort**(`core/effect_port.gd`)——职责语句「战斗业务类唯一的效果发射出口:收事件与载荷、交效果引擎结算、取回命中批」;实测形态=六 Callable 路由、bind_port 组装期转注、闭面五键 biz_fact、未绑零扰动缺省;`DamageController`/`ActionEconomy` 各持端口引用(同一实例、构造注入),`EffectEngine`/`EffectContext` 引用与计数器账面(value_counter 层值读后清零)收归宿主侧(BattleFxHost 域),业务类零引擎直连、零账面触碰;facts 取值束(dig_streak/charge_layers/rider_tier_*)与入站回调束(reveal/ac)随发射契约归宿主侧注入面;端口**单实现零接口抽象**(无基类无多态——GDScript 无 interface,本案不需要);端口与宿主经注入 Callable 束协作、零宿主对象引用(跨件单向接线条款适用,禁双向强引用)。②**掷格件 RewardRoller**(`core/reward_roller.gd`)——职责语句「装配期格面资源摇号:池行装配、区间行 roll、权重合成(偏运硬币/board_skew 两路投影)」;实测形态=roll 批束四键(mapping/power_roll/clear_identity/clear_power)、选行算子 `_weighted_pick_row` 返表行、fatal 经构造 Callable 链;受理账面(grant/身份查询/快照/retire/polarity_row)留 `RewardEconomy`,衔接面=格→奖励身份映射(掷格件产出、受理件接收);掷格件经注入 RngServiceCore 取号(roll_board 流 scope=每次 install 批不变、取号序零漂移)。行为零变化红线沿本节「验收红线」全款:命中序=声明序、明细行协议词表零触碰、`_ineffective_row` 载荷 deferred 自描述键观测面不回退(2026-11-02 迭代 48 卡① 甲案在案)、EV/MC 锚同种子逐位零漂移——round_flow 逐位回放 134 检查为主证(红线成立);两新件 S13 预算随卡「实现规范预算」三查已过(新件全默认阈值内、gdstyle 基线外新违规 0),`RewardEconomy` 类变量随掷格面迁出 15→11;S7 B1 域文件集与 S8 await 文件集已随批增行。 @@ -151,9 +155,9 @@ ### 冒险域拆分(现状登记——2026-10-26 设计闭合,2026-10-27 迭代 39 拆件批实装,本节各条即现行形态) -- **应用层形态**:adventure_runner 退出上帝对象、转薄应用层(DDD 应用层形态)——只留冒险状态机、关序推进、结算受理、建件接线、效果引擎冒险桶字典持有(桶=效果引擎域数据,应用层只锚定生命周期);零领域决策。核心层表三新件行(HeroLedger/AttuneLoadout/CurioStop)即本拆分目标。 +- **应用层形态**:adventure_runner 退出上帝对象、转薄应用层(DDD 应用层形态)——只留冒险状态机、关序推进、结算受理、建件接线、效果引擎冒险桶字典持有(桶=效果引擎域数据,应用层只锚定生命周期);零领域决策。核心层表新件行(主角账三件与刷新账件/AttuneLoadout/CurioStop——见基础层与功能层登记)即本拆分目标。 - **CurioDeck 转纯池**:bind_handlers 反向回调退役;商店购买消费经注入 Callable 链至 CurioStop 兑付单点——牌库只管抽签/消耗/cap 判定/凭证计数。 -- **RunLedger 退役**:四账各归其主——加算区/购买记录/钥石增量/特性集/真视记录归 HeroLedger,充能归 AttuneLoadout,冒险桶字典归应用层持有;战斗侧 encounter 注入面由单一账类引用改为多路(桶字典+实体账+配装件);ShopSession 账本引用面同步换代,商店属性商品加算改经 HeroLedger 单写原语。 +- **RunLedger 退役**:四账各归其主——加算区/购买记录/钥石增量/真视记录归 GainJournal、特性集归 HeroStats(GP 钱包归 GpWallet),充能归 AttuneLoadout,冒险桶字典归应用层持有;战斗侧 encounter 注入面由单一账类引用改为多路(桶字典+实体账+配装件);ShopSession 账本引用面同步换代,商店属性商品加算改经 GainJournal 单写原语。 - **level_runner**:依赖改构造注入一次给齐(后置 setter 群与商店重绑机制退役;注入活引用禁快照——特性集共享引用语义保留);商店白盒转发属性撤除;战斗→关卡信号转发族保留(战斗实例每节点新建,关卡层做战斗域稳定面)。 - **断点片段化**:各件自写自读自己的键(关卡层交关卡域五键片段:node_id/visited_ids/aux_items/shop_shelf/shop_visit_buys),缺键回退策略随领域知识归各件;应用层唯一落盘口(收齐各件片段拼成顶层快照后写盘),写触发点不变(五处);既有 27 键逐键冻结;新增获得日记键沿扩列不升版先例——旧档缺日记回退汇总键直载并跳过比对,日记在档时由日记推导汇总、与留存值不符即报错中止(迁移正确性自检)。2026-10-29 零豁免裁随动:拼盘与读侧策略机组拆出 breakpoint_store(核心层表新行),应用层落盘口与写触发点不变——宿主经件组装快照后写盘,27 键冻结不变。 - **信号直连**:adventure_runner 六转发信号族(node_entered/choices_presented/step_row/round_started/board_changed/wallet_changed)退役;呈现层在 level_started 重取点重订阅关卡对象信号(旧实例连接随引用释放消亡);「关卡开始信号前零发射」契约写进关卡件头注;「恰好连接一次」断言用 is_connected 守卫(release 模板剥 assert);三选一信号面归 CurioStop。 @@ -409,7 +413,7 @@ CJK 字体随包发行并设为 theme 默认字体——运行时默认字体无 | 各系统 → D2 | ConfigDB 类型化属性单点读取 | 禁绕过 ConfigDB load 表、禁缓存副本、禁玩法数值字面量、禁 randomize()/自建 RNG | 校验双通道 + fail-fast 致命 | | A1 → A2 | Board 产物 class_name 数据契约 | install 四不变式校验(violation = 拒绝 + 五类诊断枚举) | 生成期合法性闸(R₀≠S / clearable / min_safe) | | A1 ↔ B1 | attempt 边界非 scope 事件;actuals p10 为对账输入(非 target 参数) | 编排不把重试当取号 | 生成期指标集输出(实测可推理率 / 实际雷数与安全格数 / 重试次数 / 降级与非法产物标记) | -| B4 → B3 | buff 类经 B1 调 apply_effect(B4 零跨系统读、零直接接口) | 满层拒绝 = 零兑付 + 明细行(无折算) | 授予时数值快照(抗热重载) | +| B4 → B3 | buff 类经 B1 调 apply_effect(B4 零跨系统读、零直接接口) | 满层拒绝 = 零兑付 + 明细行(无折算) | 授予时数值快照(授予时定格) | | B1 → D1 | [步骤流行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(基础行型+扩展行两层封闭 + 公共字段 type/source_class/origin_cell/round_index/display_name/value/highlight? + 特有字段 target/effect_id/pool_value) | 无来源行 = 断言失败;呈现侧禁按行序重演 B2 状态机 | 可回放步骤流(同种子逐行相同) | **引擎类型核验注记**:接口使用的引擎类型 = Resource / .tres(D2 全表)、RefCounted(容器类)、Signal/Callable(事件载体)、Control/CanvasLayer/Drawing(D1)、SceneTree headless 协议(测试)——均属 4.x 基线稳定面;4.7 Control 域增量(offset_transform_* 等)已在 breaking-changes.md 登记,D1 采纳前对照核实。 diff --git a/design/gdd/systems/战斗循环/战斗结算.md b/design/gdd/systems/战斗循环/战斗结算.md index a361cf43..102eef72 100644 --- a/design/gdd/systems/战斗循环/战斗结算.md +++ b/design/gdd/systems/战斗循环/战斗结算.md @@ -1,7 +1,7 @@ # 战斗结算 > 一句话:轮末结算的编排与逐行兑现 -> 状态:已定稿(自旧体系迁移);现行为 v1.6 +> 状态:已定稿(自旧体系迁移);现行为 v1.7 ## 设计目的 @@ -284,7 +284,7 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值 崩壁冲击若击杀最后敌人,仍由本轮判定段按既有顺序判胜,不新增挖掘期即时胜利出口。换图系效果使用扩展行留痕:崩壁冲击走伤害单据,石层缓冲在受伤消费行体现减免,坑道小憩与矿道红利分别走治疗与 GP 入账记录。刷新事实来源不指向单一棋盘格,使用明细流水的专长刷新效果来源豁免,不伪造来源格。 -战斗开始按固定序列开张:关上配置热重载的闸门、初始化状态池、掷骰定敌方实际数量、生成敌人、装板并预分配资源恰一次、变异布置([地形变异](../排雷循环/地形变异.md)——棋盘设置顺序第 4 步:生成棋盘 → 打开状态初始化 → 战斗资源格设置 → 变异格设置,消费 `variant_place` 封闭流)、发开轮通知并执行开轮摇号(摇定首轮各敌本拍动作)。上一关的大奖励(如血上限提升)经战斗开始入参的覆盖值通道生效,内容归[冒险结构](../冒险循环/冒险结构.md)。 +战斗开始按固定序列开张:初始化状态池、掷骰定敌方实际数量、生成敌人、装板并预分配资源恰一次、变异布置([地形变异](../排雷循环/地形变异.md)——棋盘设置顺序第 4 步:生成棋盘 → 打开状态初始化 → 战斗资源格设置 → 变异格设置,消费 `variant_place` 封闭流)、发开轮通知并执行开轮摇号(摇定首轮各敌本拍动作)。上一关的大奖励(如血上限提升)经战斗开始入参的覆盖值通道生效,内容归[冒险结构](../冒险循环/冒险结构.md)。 举证:本节为编排流程,无计算。 @@ -294,7 +294,7 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值 | 方向 | 系统 | 接口要点 | |---|---|---| -| 上游 | [数据配置](../表现与支撑/数据配置.md) | 结算配置表(段序、当量、封顶、甲效与护甲等级掷点参数)的承载与读取,本系统是回填责任方;战斗中热重载被闸门拒绝 | +| 上游 | [数据配置](../表现与支撑/数据配置.md) | 结算配置表(段序、当量、封顶、甲效与护甲等级掷点参数)的承载与读取,本系统是回填责任方 | | 上游 | [行动经济](../排雷循环/行动经济.md) | 轮末两字段消息的接收方;回发换图指令、结算完成与战斗结束通知;挖掘期刷新经它扣费;五条经济契约的对账责任方 | | 上游 | [排雷玩法](../排雷循环/排雷玩法.md) | 订阅其三事件流(挖开格、封印判定、轮次结束);换图时调用装板与退役 | | 上游 | [棋盘生成](../排雷循环/棋盘生成.md) | 换图时调用其生成接口 | diff --git a/design/gdd/systems/排雷循环/棋盘生成.md b/design/gdd/systems/排雷循环/棋盘生成.md index 9559015d..21b22ef4 100644 --- a/design/gdd/systems/排雷循环/棋盘生成.md +++ b/design/gdd/systems/排雷循环/棋盘生成.md @@ -1,7 +1,7 @@ # 棋盘生成 > 一句话:棋盘怎么生成、怎么保证可推理可清图 -> 状态:已定稿(自旧体系迁移);现行为 v1.2 +> 状态:已定稿(自旧体系迁移);现行为 v1.3 ## 设计目的 @@ -61,7 +61,7 @@ ④ 产出上报 ─── 交出棋盘 + 生成期指标集 ``` -生成期间的每一次随机取数——布雷、重试——都从本图专属的一条"棋盘生成随机流"按固定顺序取:一张图只开一条流、用到底,重试不开新流;流之外零随机,全局随机函数一律禁用。参数行开始时一次快照,配置表中途热重载不影响进行中的生成。管线本身无状态——这些合起来就是"同种子同参数必产同图"的根基。(变异布置不消费本流——其取数走专用 variant_place 流,归战斗结算 布置段。) +生成期间的每一次随机取数——布雷、重试——都从本图专属的一条"棋盘生成随机流"按固定顺序取:一张图只开一条流、用到底,重试不开新流;流之外零随机,全局随机函数一律禁用。参数行开始时一次快照。管线本身无状态——这些合起来就是"同种子同参数必产同图"的根基。(变异布置不消费本流——其取数走专用 variant_place 流,归战斗结算 布置段。) 各阶段的失败都有明确语义,全部失败路径都不让玩家卡死(本节为纯流程规则,无计算;数值与校验式见后续各节): diff --git a/design/gdd/systems/表现与支撑/数据配置.md b/design/gdd/systems/表现与支撑/数据配置.md index eb46fa93..d63d89ae 100644 --- a/design/gdd/systems/表现与支撑/数据配置.md +++ b/design/gdd/systems/表现与支撑/数据配置.md @@ -1,7 +1,7 @@ # 数据配置 > 一句话:数值表与单一事实源管线 -> 状态:已定稿(自旧体系迁移);现行为 v1.2 +> 状态:已定稿(自旧体系迁移);现行为 v1.3 ## 设计目的 @@ -19,7 +19,7 @@ |---|---| | 全部数值表的结构与数据 | 表结构类(声明每列的类型、取值域与默认值)与数据文件成对交付;结构先行,数值由各回填责任方回填 | | 全局读取口与随机服务 | 两个进程级单例:类型化读取口与统一随机流服务 | -| 加载、校验与热重载管线 | 启动加载、fail-fast 校验、调试构建热重载的状态管理 | +| 加载与校验管线 | 启动加载、fail-fast 校验 | | 进度坐标查行 | 进度键表(跟着冒险进度成长的表)按(关卡序号 × 节点深度)两维坐标解析取行 | | 表清单与对账 | 表路径固定、清单封闭;表实与 schema 声明逐字段对账 | @@ -46,7 +46,7 @@ 单一事实源(本文含义:每个玩法数值只有一处权威载体,其余一律引用它)落到两条禁令上。第一,玩法代码零数值字面量:凡是设计师要调的数字,只存在于 data/tables/ 下的数据表里,代码里写死玩法数值即评审阻塞项。 -第二,取数只走一个口:全部系统经全局读取口的类型化属性读数(读出来就是带类型的值,例如每轮行动点就是行动经济表里那个整数字段),禁止绕过它自己加载表文件或长期缓存副本——副本绕过校验,热重载换新值时它也不知情。 +第二,取数只走一个口:全部系统经全局读取口的类型化属性读数(读出来就是带类型的值,例如每轮行动点就是行动经济表里那个整数字段),禁止绕过它自己加载表文件或长期缓存副本——副本绕过校验,不在单一事实源管线内。 表结构与数据成对交付:结构定义先行(每个字段带类型、取值域与默认值),本系统先建齐全部占位表,具体数值由回填责任方按其系统文档回填——先有格子,后填数字。表结构零界面依赖:本系统代码不引用任何界面类,无窗口的命令行模式(headless)下也能跑完整战斗,自动化测试才有载体。 @@ -109,7 +109,7 @@ └─ 任一错误 ──▶ 输出错误清单,致命中止 ``` -热重载(不重启进程、当场重新加载表文件的调试手段,仅调试构建)单独一套处置:战斗进行中的重载请求被闸门拒绝(闸门由[战斗结算](../战斗循环/战斗结算.md)在战斗开始时置位、结束复位),重载校验失败时保留旧表继续运行并给出错误清单——不杀调试会话,这是全部规则里唯一的软着陆。调试构建之外,加载与校验在任何构建形态一律致命。随机服务的状态线独立于表加载:重载成败都不触碰主种子与计数器。 +加载与校验在任何构建形态一律致命:任一表加载或校验失败,输出错误清单并致命中止——fail-fast 全域统一,无软着陆例外。随机服务的状态线独立于表加载:加载成败都不触碰主种子与计数器。 举证:本节为处置纪律约定,无计算。校验双通道与夹具注入为实现参照,本文不转载。 @@ -151,13 +151,12 @@ | 下游 | [敌人系统](../战斗循环/敌人系统.md) | 敌人表与主角表承载 | | 下游 | [增益状态](../战斗循环/增益状态.md) | 状态效果表承载;悬空引用校验的被指方 | | 下游 | [地图战斗资源](../战斗循环/地图战斗资源.md) | 奖励表与奖励配置表承载;reward_roll 流取号 | -| 下游 | [战斗结算](../战斗循环/战斗结算.md) | 结算表承载;热重载闸门置位与复位;encounter 流取号 | +| 下游 | [战斗结算](../战斗循环/战斗结算.md) | 结算表承载;encounter 流取号 | | 下游 | [秘宝](../跨局循环/秘宝.md) | 秘宝表承载 | | 下游 | [冒险结构](../冒险循环/冒险结构.md) | 关卡表与冒险表承载(登记现状见「待办」);主种子注入入口 | | 下游 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | 难度表承载(占位);进度坐标查行的消费方 | | 下游 | [元进度](../跨局循环/元进度.md) | 元进度表占位承载 | | 下游 | [存档序列化](存档序列化.md) | 随机快照契约(主种子 + 全局取数计数器) | -| 下游 | [HUD 框架](HUD框架.md) | 调试热重载完成通知(仅调试构建) | | 外发 | 无订阅 | 本系统不订阅任何玩法事件 | ## P0 最小闭环 @@ -167,8 +166,7 @@ 3. 进程启动:逐表加载、逐表校验,错误收集后统一显示错误;全绿进入就绪态。 4. 全部系统经全局读取口读数,无第二取数路径。 5. 冒险开始注入主种子并开事件日志会话,统一流按事件取号。 -6. 调试构建热重载即改即验:战斗中被闸门拒绝,结束后手动再触发。 -7. 无窗口冒烟脚本跑通加载、校验、取数、派生全链路,退出码 0。 +6. 无窗口冒烟脚本跑通加载、校验、取数、派生全链路,退出码 0。 ## P1 / P2 后置 @@ -178,7 +176,6 @@ | P1 | 难度曲线导出工具(无窗口导出行解析矩阵供比对) | 难度审计的离线载体,[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)期交付物 | | P2 | 正式包构建的致命表现验证与调试覆盖结构性不存在验证 | 挂首次正式导出检查清单 | | P2 | 进度键表的调试覆盖行寻址语法 | 调试覆盖现只支持单行全局表字段,行寻址登记为后续扩展 | -| P2 | 编辑器内表文件热重载自动化 | 低优先,未指派 | ## 调参表 @@ -198,10 +195,9 @@ - 校验类别全覆盖:越界、文件缺失、空表、缺锚行、重复键、权重和为零、悬空引用各有一份测试夹具,逐类断言错误类别。 - 致命真的会死:任一致命夹具经正式通道加载,进程非 0 退出,而非仅"校验器能发现"。 - 黄金向量:随机派生纯函数对登记向量逐个复算相等;同输入恒同输出;同序号重复调用恒等。 -- 计数器纪律:连续取号跨模拟关卡切换,计数器单调不重置;热重载成败都不改变主种子与计数器。 +- 计数器纪律:连续取号跨模拟关卡切换,计数器单调不重置;表加载不改变主种子与计数器。 - 向上取整解析:请求无精确行时返回**不低于**请求坐标的最近行并留一条警告;请求超出最大已有行时封顶取最大行并留警告;同类警告去重;精确命中零警告。 - 越域与未播种:坐标低于合法域(关卡序号 <1、节点深度 <0)在进入解析前致命中止(Fatal 级诊断 + 进程非 0 退出,无兜底);高于最大已有行走封顶取最大行(警告留痕,不致命);未设主种子就取随机数致命中止,无默认种子兜底。 -- 热重载门:战斗中重载被拒绝且读数不变、不发通知;门未置位时新值可读且通知恰一次;校验失败保留旧表停留就绪态。 - 零字面量、零第二路径:静态扫描加人工复核确认玩法代码无数值字面量、无读取口之外的表加载、无全局随机函数调用。 - 零界面依赖:本系统代码不引用任何界面类,无窗口实跑通过(静态扫描与实跑两项合成判定)。 - 表实一致:各表结构与已锁字段和表结构声明逐字段一致。 From 3e42acdb80285160d0742438440adac6895fedd0 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 3 Nov 2026 07:07:25 +0800 Subject: [PATCH 07/19] =?UTF-8?q?=E5=86=99=E5=8D=A1(=E6=9E=B6=E6=9E=84?= =?UTF-8?q?=E5=AE=A1=E6=9F=A5P2=E4=BB=A3=E7=A0=81=E9=9D=A2=E6=89=B9=C2=B7?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=8E=88=E6=9D=83):=20EC8=E7=83=AD=E9=87=8D?= =?UTF-8?q?=E8=BD=BD=E6=AD=BB=E9=93=BE=E9=80=80=E5=BD=B9+NODE=5FTYPES?= =?UTF-8?q?=E8=AF=8D=E8=A1=A8=E5=8D=95=E7=82=B9=E5=8C=96=E9=9C=80=E6=B1=82?= =?UTF-8?q?=E5=8D=A1=E2=80=94=E2=80=94R1=E5=85=AB=E5=A4=84=E5=88=A0(config?= =?UTF-8?q?=5Fdb=20:45=E6=88=90=E5=91=98+:174-186=E9=97=A8=E4=B8=8Ereload?= =?UTF-8?q?=E4=B8=A4=E6=96=B9=E6=B3=95=E4=B8=A4=E8=AF=8A=E6=96=AD/battle?= =?UTF-8?q?=5Forchestrator=20:272/:633=E4=B8=A4=E5=BC=80=E9=97=A8=E7=82=B9?= =?UTF-8?q?;=20=E9=9B=B6=E8=B0=83=E7=94=A8=E6=96=B9=E9=9B=B6=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=BC=95=E7=94=A8grep=E5=AE=9E=E6=A0=B8)+R2=E8=AF=8D?= =?UTF-8?q?=E8=A1=A8=E5=BD=92=E4=B8=80(level=5Ftable.gd=20schema=E5=8D=95?= =?UTF-8?q?=E7=82=B9,=E7=94=9F=E6=88=90=E5=99=A8:166=E6=94=B9LevelTable.NO?= =?UTF-8?q?DE=5FTYPES=E7=9B=B4=E5=BC=95=E2=80=94=E2=80=94S3=E8=B1=81?= =?UTF-8?q?=E5=85=8D=E9=9D=A2=E5=9C=A8=E6=A1=88=E5=BD=A2=E6=80=81);=20?= =?UTF-8?q?=E9=9B=B6=E8=A1=8C=E4=B8=BA=E5=8F=98=E6=9B=B4=E6=89=B9(sweep?= =?UTF-8?q?=E5=9B=9B=E6=96=AD=E8=A8=80=E5=B8=A6=E9=9D=9E=E7=A9=BA=E5=89=8D?= =?UTF-8?q?=E7=BD=AE=E6=AD=A3=E9=94=9A=E3=80=94=E6=9E=B6=E6=9E=84P2=20V1-V?= =?UTF-8?q?4=E3=80=95+node=5Fmap=5Fdeterminism=E7=A1=AE=E5=AE=9A=E6=80=A7?= =?UTF-8?q?=E9=93=BE=E9=80=90=E4=BD=8D+config=5Fdb=5Fresolver/battle=5Fset?= =?UTF-8?q?tlement=E6=97=A2=E6=9C=89=E5=85=A8=E5=A5=97);=20T1+T2=E4=BC=B0?= =?UTF-8?q?=E6=97=B60.5=E5=B7=A5=E4=BD=9C=E6=97=A5,=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E5=9C=A85.1=E5=8D=A1=E5=90=8E(battle=5Forchestrator=E5=90=8C?= =?UTF-8?q?=E6=96=87=E4=BB=B6);=20=E8=83=BD=E5=8A=9B=E8=A1=8C=E5=9B=9B?= =?UTF-8?q?=E6=AE=B5=E5=85=A8=E9=83=A8=E5=9C=A8=E5=86=8C=E5=AE=9E=E5=90=8D?= =?UTF-8?q?;=20=E5=BE=85=E5=8A=9E=E6=B8=85=E5=8D=95=E6=9D=A1=E7=9B=AEP2?= =?UTF-8?q?=E9=83=A8=E5=88=86=E6=8E=A8=E8=BF=9B=E5=B7=B2=E5=86=99=E5=8D=A1?= =?UTF-8?q?(=E6=9C=AA=E9=97=AD=E5=90=88=E4=BD=99=E9=A1=B9=E6=94=B6?= =?UTF-8?q?=E7=AA=84);=20pipeline=5Fgate=20PASS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../需求卡片-架构审查P2代码面批-2026-11-03.md | 165 ++++++++++++++++++ 待办清单.md | 2 + 2 files changed, 167 insertions(+) create mode 100644 reports/需求卡片-架构审查P2代码面批-2026-11-03.md diff --git a/reports/需求卡片-架构审查P2代码面批-2026-11-03.md b/reports/需求卡片-架构审查P2代码面批-2026-11-03.md new file mode 100644 index 00000000..e0f61333 --- /dev/null +++ b/reports/需求卡片-架构审查P2代码面批-2026-11-03.md @@ -0,0 +1,165 @@ +# 需求卡片:架构审查 P2 代码面批(2026-11-03) + +来源:待办清单「架构审查优化讨论——全库架构审计读数的逐条裁决与整改分批(2026-10-29 登记,来源=审计发现)」条目 P2 部分(**唯一事实源**:reports/审计-全库架构审查-2026-10-29.md §5.2 EC8 项+§5.3 NODE_TYPES 项+2026-11-03 设计讨论会话用户授权〔实现层事项按代码规则与架构文档决策——EC8 退役依用户总判据 3「死代码不保留」2026-11-02 先例〕;GDD 侧规格退役凭据=arch51-docs worktree 提交 63fc3e74〔数据配置.md v1.3/战斗结算.md v1.7/棋盘生成.md v1.3〕)。 +状态:已写卡(v1.0,2026-11-03 成文)。改动面:游戏代码(含随逻辑写/改的测试代码)。 + +## 1. 目标与完成定义 + +**这批做什么**:两处零行为变更的代码面退役与单点化——审计 §5.2/§5.3 的 P2 代码遗留: + +| # | 对象 | 现状 | 终态 | +|---|---|---|---| +| R1 | EC8 热重载死链 | `config_db.gd` 门标志+两方法+两诊断(:45/:174-186);`battle_orchestrator.gd` 两处开门点(:272/:633);`reload()` 全仓零调用方、走 `load()` 命中引擎资源缓存拿不到磁盘新值——门后入口死(GDD 侧规格已随文档批退役) | 八处整段删除;配置库公开面 8→6;诊断状态机零触碰(删除面全部在 reload 体内) | +| R2 | NODE_TYPES 词表双份 | `node_map_generator.gd:10` 与 `level_table.gd:11` 各持一份(内容同、序不同);生成器 :166 校验自产节点、schema :78 校验表行——校验双活、词表双写 | 词表单点归 schema(`LevelTable.NODE_TYPES`),生成器删本地副本改 class_name 直引;两处校验语义零变化(`.has()` 只判成员、序无关) | + +**什么状态算完**:八处删除与词表改指落码、各有第 8 节对照表配对的验收断言在当轮真实跑批中通过;零行为变更证明=既有套件零转红(config_db_resolver/node_map_determinism/battle_settlement/冒烟)+结构性 sweep 恒零(第 8 节 V2/V3);代码域闸全绿;两份 reports/ 产出物(实现报告+反哺点清单)写齐。 + +**排序义务**:本卡实现排队在 reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md 之后——battle_orchestrator.gd 同文件(5.1 卡重写 `_init` 与三调用点,本卡删 :272/:633 两行;后卡行号以 grep 符号锚定位)。 + +## 2. 设计事实源 + +- **审计读数**:`reports/审计-全库架构审查-2026-10-29.md` §5.2 第三行(EC8:`ConfigDb.reload()` 全仓零调用方、缓存命中拿不到磁盘新值、门被真实开合但门后入口死)+§5.3(NODE_TYPES 词表双份)。 +- **裁决凭据**:2026-11-03 设计讨论会话用户授权(实现层事项按代码规则与架构文档决策)+用户总判据 3「死代码不保留」(2026-11-02 裁,3.1+3.2 批死效果通道同款判法先例)。 +- **GDD 侧已闭合**:arch51-docs 提交 63fc3e74——数据配置.md v1.3(热重载规格八处摘除、软着陆例外消失=fail-fast 全域统一)、战斗结算.md v1.7(开张序列去关门步)、棋盘生成.md v1.3(热重载从句删)。本卡只收代码面。 +- **架构登记**:`design/engineering/architecture/architecture.md` v1.32——:88 ConfigDB 行(公开面 8 现态登记)、:386-387 战斗序列现态、:123 battle_orchestrator 行 `set_reload_gate` 指称。 + +## 3. 现状事实(2026-11-03 master 工作区实查,基点 ab5d75a2;开工自行复核) + +- **EC8 代码链八处**:config_db.gd:45(`var _reload_gate := false`——类变量第 9 个声明位);:174-186(注释行+`set_reload_gate` :176-177+`reload()` :180-186——内含 `push_diag("warning","reload_gated",...)` 与 `push_diag("debug","config_reloaded",...)` 两诊断与 `load_tables("res://data/tables", false)` 调用);battle_orchestrator.gd:272(begin_battle 序内 `db.set_reload_gate(true)`)与 :633(battle_over 清理序内 `db.set_reload_gate(false)`)。全仓 `reload_gated`/`config_reloaded`/`EC8` 字符串在 config_db.gd 之外零命中(grep 实核——测试/呈现/模拟/探针四层全零);`reload()` 调用方全仓零命中;tests 对 reload/热重载零引用。`load_tables` 本体(:131-159 一带)被启动加载与 resolver 装配真实消费——**只删门与 reload,load_tables 零触碰**。 +- **NODE_TYPES 双份**:`core/node_map_generator.gd:10`(`["battle", "boss", "reward", "rest", "shop"]`)与 `data/schemas/level_table.gd:11`(`["battle", "reward", "rest", "boss", "shop"]`+注释「关卡节点地图 v2.1」);消费点=node_map_generator.gd:166(`NODE_TYPES.has(String(n["type"]))`——生成器自产节点枚举校验)与 level_table.gd:78(表行加载校验)。全库第三处引用零命中(grep 实核——tests/sim/probe 全零)。两处消费均为 `.has()` 成员判定,词表序不参与行为(内容集相同)。 +- **闸面现状**:S3(core 禁表加载)对 schema class_name 直引是豁免面(warning 级人工复核口径,static_scan.sh S3 注释「schema class_name 直引豁免」)——生成器改引 `LevelTable.NODE_TYPES` 落在既有豁免形态内(同款先例=config_db 持 BoardGenTable 等四域容器);零闸件改动。 +- **S13 预算**:config_db 公开方法 8(删 set_reload_gate/reload → 6)、类变量 10(删 `_reload_gate` → 9);node_map_generator 公开面与类变量零变化(删常量不涉成员账);battle_orchestrator 15 贴顶件零变化(删两行语句不涉成员)。gdstyle 基线(tools/gdstyle_baseline.txt)对本批触件零登记键(config_db/node_map_generator/battle_orchestrator 均无登记值)。 + +## 4. 设计契约(违反即返工红线) + +- 🔴 **零行为变更**:R1 删除面全部为死代码(门标志唯一消费者 reload 自身零调用方);R2 词表 `.has()` 判定集相同——两需求的零变更证明=既有套件零转红+同种子确定链零漂移(node_map_determinism 全绿)。RNG 封闭流、明细行协议、诊断状态机、存档与断点链零触碰。 +- 🔴 **R1 删除边界**:只删 `_reload_gate` 成员+`set_reload_gate`+`reload()`+编排器两行开门点;`load_tables`/`push_diag`/诊断状态机/其余公开面零触碰;禁留兼容别名、禁留转发壳、禁注释化残段(第 13 节全款适用)。 +- 🔴 **R2 单点方向**:词表唯一落点=`data/schemas/level_table.gd`(表行校验 owner);生成器删本地 `const NODE_TYPES`,:166 改 `LevelTable.NODE_TYPES.has(String(n["type"]))`——core→data/schemas 前向边,schema class_name 直引(S3 豁免面在案形态);禁反向(schema 引 core);禁把词表搬进第三处(词表唯一落点不可迁)。 +- 🔴 **fail-fast 不破**:删除不引入任何软回退;配置加载校验路径零改动。 +- 🔴 **测试纪律**:禁变异类测试、禁撤销类取证;禁删断言/放宽阈值(第 8 节申报清单之外零删改)。 + +## 5. 范围边界 + +**收件**=R1 八处删除+R2 词表单点化+两件新 sweep 测试+既有套件回归确认。 + +**不收件**(去向已指认): +- architecture.md :88 公开面 8→6/类变量 10→9、:123 行 `set_reload_gate` 指称、:386-387 战斗序列两行——**反哺点清单承载**(实现批禁写 design/,第 6 节)。 +- GDD 侧热重载规格——已随文档批退役(63fc3e74),本卡零 GDD 触碰。 +- 闸面缺口(S1/S2/S9/S13 扫描面扩 sim/probe/tests、S8 目录域)与 S13 三处豁免存废——审计 P1 项,**不在本卡**(待办清单条目未闭合余项,后续讨论段)。 +- `ConfigDb.reload` 的诊断字符串(reload_gated/config_reloaded)随方法体整删——诊断状态机其余类别零触碰。 + +## 6. 关联文档同步面 + +实现批禁写 `design/` 整个目录与根规则文件;下表每条的落文义务全部进 `reports/iter-反哺点-<日期>.md`(N=编排段定),由用户裁决后归文档批落文: + +| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务(反哺点清单逐条承载) | +|---|---|---| +| design/engineering/architecture/architecture.md | :88 ConfigDB 行「公开面 8(…set_reload_gate/reload)」→ 6、类变量 10→9;:123 battle_orchestrator 行消费依赖「D2 SettlementTable + set_reload_gate」→ 去 set_reload_gate 指称;:386-387 战斗序列「set_reload_gate(true)→」「→ set_reload_gate(false)」两段删除;node_map_generator 相关行如有词表双份表述随 R2 订正(写卡期 grep「NODE_TYPES|词表」复核——现登记 :119 行「各持一份 NODE_TYPES 词表」随单点化删句) | 反哺点清单逐条列行号与改后登记内容——**机械面文档禁直改** | +| design/gdd/systems/表现与支撑/数据配置.md | 无陈述变化(v1.3 已退役全部热重载规格——零反哺确认行) | 反哺点清单写「零反哺」确认行 | +| 术语表 | 无新术语 | 确认行「零新增术语」 | + +(机检口径:本表同步义务格无一条写「随批」。) + +## 7. 任务卡 T1..T2 + +### 卡前·文件结构图 + +全部行为面=非行为改动(零行为变更批),行标【非行为】+对照表 R 行号;测试件为随逻辑写/改的测试代码。 + +``` +core 层 + game/core/config_db.gd 【非行为 R1】:45 成员删+:174-186 门与 reload 整段删(公开面 8→6、类变量 10→9) + game/core/battle_orchestrator.gd 【非行为 R1】:272/:633 两行删 + game/core/node_map_generator.gd 【非行为 R2】:10 本地词表删+:166 改 LevelTable.NODE_TYPES.has(...) +测试件(随逻辑写/改) + tests/unit/core/encapsulation_p2_sweep_test.gd 【非行为 R1–R2·新增】两处结构性零命中扫描(非空前置+正锚) + tests/run_all.gd 【非行为】manifest +1 行(sweep) +文档件 + game/tests/README.md 写卡段判断=零编辑(第 8 节能力行判断依据)——实现批禁写,批末只核对能力名引用一致 +``` + +--- + +**T1 EC8 死链退役**(估时 0.25 工作日;区间 0.25–0.5) +取用:无(本卡起点)。产出:R1 八处清零+sweep R1 组绿。 + +- [ ] 核对实现排序在案:5.1 卡(含 battle_orchestrator 触面)未合回则本批不开工;:272/:633 现址复核(行号漂移以 `db.set_reload_gate` 符号锚定位,漂移即记录进实现报告,禁改判据) +- [ ] config_db.gd::45 `_reload_gate` 成员删;:174-186 整段删(注释行+两方法+两诊断);删除后 grep 自查 `reload` 于本文件仅剩注释性零命中(load_tables 文档注释如有 reload 字样一并订正) +- [ ] battle_orchestrator.gd::272 行删(begin_battle 序内——`_damage.set_hero_ac_override(...)` 行之后);:633 行删(battle_over 清理序内——`action_economy.notify_combat_end()` 行之后);两删除点上下语句序零变化 +- [ ] 新增 tests/unit/core/encapsulation_p2_sweep_test.gd(extends SceneTree+Kit.check 主通道,全类型标注;源 token 扫描手法沿 encapsulation_sweep_test.gd〔5.1 卡新增件〕先例)R1 组:①config_db.gd 非空+含 `class_name ConfigDb` 正锚+`set_reload_gate|_reload_gate|func reload|reload_gated|config_reloaded` 全文零命中〔架构P2 V1〕;②battle_orchestrator.gd 非空+`set_reload_gate` 零命中〔架构P2 V2〕——两组均带扫描面非空前置 +- [ ] 孤立验证:新 sweep 单件先跑绿(含改前红态确认——sweep 对未删码当轮命中即红,属断言对现状的正当判红,非变异测试);随后 config_db_resolver_test 全套+battle_settlement 套件+冒烟零转红 +- [ ] run_all.gd manifest 追加 1 行:encapsulation_p2_sweep_test(expect 0,注记「R1–R2 结构性零命中扫描〔架构P2〕」) + +**T2 NODE_TYPES 单点化+批收口**(估时 0.25 工作日;区间 0.25–0.5) +取用:T1 sweep 骨架。产出:R2 清零+批收口两件。 + +- [ ] node_map_generator.gd::10 本地 `const NODE_TYPES` 删;:166 改 `if not LevelTable.NODE_TYPES.has(String(n["type"])):`——头注如有词表自述随改 +- [ ] sweep 测试 R2 组:③node_map_generator.gd 非空+`^const NODE_TYPES` 零命中+`LevelTable.NODE_TYPES.has(` 正锚〔架构P2 V3〕;④全仓 .gd 生产面(core/data/presentation)`NODE_TYPES :=` 定义恰好 1 处且落 data/schemas/level_table.gd〔架构P2 V4〕 +- [ ] 孤立验证:node_map_determinism_test 全套绿(生成链同种子逐位——R2 零行为变更主证)+关卡表加载路径(level_table 校验活检查)经既有套件覆盖零转红 +- [ ] **实现报告** `reports/iter-实现报告-<日期>.md`:各卡状态+S13 键改前改后对账(config_db 公开 8→6/类变量 10→9 现场读数)+实现决定记录 +- [ ] **反哺点清单** `reports/iter-反哺点-<日期>.md`:第 6 节同步面逐条落点(architecture.md 四处、GDD/术语确认行) +- [ ] 批末核对:README 能力名引用一致(本卡零编辑);独立验收审计(第 8 节末)未过不合并;.uid 收口=`--editor --quit` 一次后确认新测试件 .uid 随批提交 + +### 估时汇总 + +T1 0.25|T2 0.25。区间合计 0.5–1.0 工作日;**精确汇总 0.5 工作日**(超 1 工作日=超卡面估时域,须用户确认后方可续批)。 + +## 8. 验证闸(改动—验收对照表) + +测试方式两分法:下表全部走**调试接口验证**;**正常流程体验验证**=零项(零行为变更批)。判据绑被测改动特有的可观测提交面(源码零命中带非空前置与正锚/确定链同种子逐位)。 + +| 需求点 | 改动(文件:行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 | +|---|---|---|---|---|---|---| +| R1 EC8 死链退役 | config_db :45/:174-186 删+battle_orchestrator :272/:633 删 | encapsulation_p2_sweep_test R1 组〔架构P2 V1/V2〕;config_db_resolver_test 既有全套(加载/校验/解析面零转红);battle_settlement 套件+冒烟零转红(战斗序列少两行后全链逐位) | 单元+集成 | `ConfigDB.load_tables()`(启动加载)→`BattleOrchestrator.begin_battle()`→battle_over 全链 | 源码五符号零命中(非空前置);解析/加载/结算行为面零漂移 | 既有:加载期违规表拒绝:跨表悬空/计数器前缀/真视窄域/效果类型出域;既有:轮内流与结算五段全序 | +| R2 NODE_TYPES 单点化 | node_map_generator :10 删+:166 改指 | encapsulation_p2_sweep_test R2 组〔架构P2 V3/V4〕;node_map_determinism_test 既有全套(同种子同参数必产同图逐位) | 单元+集成 | `LevelRunner` 关卡推进→节点图生成真实入口;`LevelTable` 表行加载校验 | 词表定义唯一落点(正锚计数=1);生成链同种子逐位同 | 既有:节点图生成合法性与同种子复现;既有:起关/选路/断点重生成同图(集成) | + +**零行为改动面的证据义务**:本卡两行均为非行为改动——每行零变更证明=既有套件零转红+sweep 恒零+(R2)确定性链逐位。能力行全部「既有」、零新增——判断依据:零行为变更=玩家可观测能力面零变化;能力清单零编辑(批末核对义务在 T2)。 + +**闸口径**:重闸=`tools/run_all_gates.sh` 按本批改动域选档(改动含 game/ 下非 .md 行为载体 → `--code`);所选域全绿才合并。卡内不写死闸件名单。回归措辞:里程碑卡出口跑一次全套闸;卡内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套。 + +**测试削弱申报**:零条——本批零删改既有断言(grep 实核:tests 对 reload/EC8/NODE_TYPES 零引用,无断言需要迁移)。 + +**独立验收审计**:入口=批末 T2 后、合并前;报告=`reports/iter-验收审计-<日期>.md`;由没参与实现的会话或子代理执行,核对:对照表逐行断言真实存在且当轮通过、sweep 非空前置在案、零删改核对、S13 键只降不升对账。未过不合并。 + +## 9. 异常分级 + +- **L1 自救**:删除行错位一行、sweep 正则笔误、注释错字——就地改,记录进实现报告。 +- **L2 记录继续**:行号 ±5 行内漂移(grep 符号锚定位后继续)。 +- **L3 停机写报告等用户**:①实现中发现 `reload()`/`NODE_TYPES` 出现卡面未登记的第三处消费面(现状事实失实=上游缺陷,禁代裁);②删除后任一既有套件转红(零行为变更契约被破=停卡,禁就地调和);③机检键与卡片契约互斥=停卡呈报,禁自造第三条路。 + +## 10. 代拍板白名单 + +- sweep 正则具体写法与断言消息措辞(尾缀〔架构P2 Vn〕与判别词保留)。 +- 删除点上下空行/注释的整理(语句序不变)。 +- 逐卡内「孤立验证→出红最小单元→并入全套」执行顺序细节。 +超清单的决断记入实现报告「实现决定记录」节。 + +## 11. 待裁点 + +**零待裁点,开工门=U0**——两处退役/单点化方向均由审计读数+用户总判据 3(死代码不保留)+2026-11-03 会话授权导出;删除边界、单点落点、T 卡分解、验收断言由写卡期实查定死(第 3/7 节)。本卡未新增备选案。 + +## 12. 落位与可复用性预检 + +**新增文件(1 件,测试件)**: +- tests/unit/core/encapsulation_p2_sweep_test.gd——为什么不能复用 5.1 卡的 encapsulation_sweep_test.gd:两卡独立 worktree 独立实现批(合回顺序未定,并件会让扫描面归属与尾缀语义跨批纠缠);本卡 sweep 仅两组四处、体量小;扫描手法同源(源 token 扫描先例),合回后如需并件归后续纯测试维护批裁决。grep 同名零命中。 + +**新增函数/成员**:零(纯删除+一处改指——无任何新增生产函数/成员/数据件)。 + +**复用既有**:源 token 扫描手法=encapsulation_sweep_test/player_copy_sweep_test 先例;manifest 登记=run_all.gd 既有条目族;schema class_name 直引形态=config_db 域容器四先例。 + +**分层与交互面**:R2 前向边 core→data/schemas=S3 豁免面在案形态(同 config_db 持表容器方向);零新增跨域路径、零新依赖;RngService 红线零触碰;Core 零 UI 红线零触碰;数值单一事实源零触碰(零表改动)。 + +## 13. 禁为机检文本保留无效成员 + +本卡为退役/收敛类卡:删除面禁留兼容别名、转发壳、注释化残段(`set_reload_gate`/`reload`/`_reload_gate` 删除后禁以任何形态残留);词表删除后生成器禁留本地副本或镜像常量。机检键与卡片契约互斥时实现段一律停卡呈报,不得自造第三条路。 + +## 14. 实现规范预算 + +新增 .gd 仅 1 个测试件(SceneTree 脚本,全类型标注、零公开生产面)。生产代码全部落既有件,按「存量触面一查」对账(S13 默认阈值): +- **净减件**:config_db 公开 8→6、类变量 10→9;battle_orchestrator 零成员变化(两行语句删);node_map_generator 零成员变化(常量删+一处改指)。 +- **存量触面 S13 预期**:触件三件 S13 键较现场基线只降不升(净删为主);gdstyle 基线对三件零登记键,T1 现场读数即对账基线。 +- **指标例外申报**:无。 + +## 15. 拆分边界纪律 + +本卡零新拆件——三触件全部架构在册既有件,只做死代码退役与词表单点化;逐件职责语句不变(config_db=加载/校验/override/诊断门面〔reload 非其现行职责——死链随批清除〕;node_map_generator=关卡节点图生成域唯一承载〔词表消费方身份不变、定义权归 schema owner〕)。单一变化原因=封装与单一事实源(死链清零、词表归一),非阈值驱动。禁凑计数袋:本卡无成员打包面。先例=3.1+3.2 批甲案死效果通道退役(EFFECT_KINDS 摘名+分支删除,用户总判据 3 同款判法)。 diff --git a/待办清单.md b/待办清单.md index f185a3f8..cc95b5dc 100644 --- a/待办清单.md +++ b/待办清单.md @@ -20,6 +20,8 @@ **2026-11-02 写卡(2026-11-03 修订闭合)**:需求卡片 reports/需求卡片-架构审查3.1+3.2整改批-2026-11-02.md(v1.2——子代理写卡+grilling 一轮 19 条折入+godot-master 式终审 4 条折入,pipeline_gate PASS,worktree 提交 2f43b81d);11 张 T 卡估时合计 8 工作日(超 10 须特批提示在卡);能力行 10 增 5 改 1 删已入 game/tests/README.md。 +**2026-11-03 P2 部分(5.1 封装+5.2 文档漂移+5.3 词表)推进**:5.1 设计闭合+已写卡——处置记录落 arch51-docs worktree、需求卡片 v1.1(godot-master 终审七项折入,pipeline_gate PASS)落 arch51-card worktree,两件随各自合回落 master 后互见;5.2 文档漂移四处归真已落档(architecture.md v1.32——HeroLedger 行拆件四件补登记/冻结计数摘除/MetaProgression 补登记行;EC8 GDD 侧规格退役=数据配置.md v1.3+战斗结算.md v1.7+棋盘生成.md v1.3,arch51-docs worktree 提交 63fc3e74,文档域闸全绿);5.3+EC8 代码面已写卡——凭据=reports/需求卡片-架构审查P2代码面批-2026-11-03.md v1.0(本条目所在 master 基点 ab5d75a2 的 archp2-card worktree,零待裁点,估时 0.5 工作日,排序在 5.1 卡后);**未闭合余项收窄**=闸面缺口(S1/S2/S9/S13 扫描面、S8 目录域)、S13 三处豁免存废、零测试点名四件、presentation 层私取面约 227 行(另开设计讨论)。 + **改动面**:文档+游戏代码+工具代码 **状态**:文档设计已闭合+已写卡+已编迭代 50 From e614773aecef54ed30d9d631ebc74665321c2afc Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 3 Nov 2026 23:50:52 +0800 Subject: [PATCH 08/19] =?UTF-8?q?=E6=96=87=E6=A1=A3=E8=AE=BE=E8=AE=A1(?= =?UTF-8?q?=E6=9E=B6=E6=9E=84=E5=AE=A1=E6=9F=A55.2=C2=B7EC8=E6=92=A4?= =?UTF-8?q?=E5=9B=9E=C2=B7=E7=94=A8=E6=88=B7=E8=A3=81):=20=E7=83=AD?= =?UTF-8?q?=E9=87=8D=E8=BD=BD=E8=A7=84=E6=A0=BC=E6=81=A2=E5=A4=8D=E5=8E=9F?= =?UTF-8?q?=E7=8A=B6=E2=80=94=E2=80=94=E7=94=A8=E6=88=B7=E8=A3=81=E5=86=B3?= =?UTF-8?q?=E8=BF=91=E6=9C=9F=E5=B0=86=E5=AE=8C=E5=96=84=E5=AE=9E=E8=A3=85?= =?UTF-8?q?(=E5=AE=9E=E8=A3=85=E5=8E=BB=E5=90=91=3D=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=8F=A6=E7=AB=8B=E5=BE=85=E5=8A=9E=E6=9D=A1=E7=9B=AE+?= =?UTF-8?q?=E4=BB=96=E4=BC=9A=E8=AF=9D=E5=86=99=E5=8D=A1,=E8=A7=84?= =?UTF-8?q?=E6=A0=BC=E5=8D=B3=E5=AE=9E=E8=A3=85=E5=BA=95=E7=A8=BF),?= =?UTF-8?q?=E6=9C=AC=E6=89=B9=E4=B8=80=E5=BA=A6=E6=91=98=E9=99=A4=E7=9A=84?= =?UTF-8?q?GDD=E4=BE=A7=E8=A7=84=E6=A0=BC=E5=85=A8=E9=83=A8=E6=92=A4?= =?UTF-8?q?=E5=9B=9E:=E4=B8=89=E4=BB=BDGDD(=E6=95=B0=E6=8D=AE=E9=85=8D?= =?UTF-8?q?=E7=BD=AE/=E6=88=98=E6=96=97=E7=BB=93=E7=AE=97/=E6=A3=8B?= =?UTF-8?q?=E7=9B=98=E7=94=9F=E6=88=90)checkout=E5=9B=9E=E9=80=80=E8=87=B3?= =?UTF-8?q?=E6=9C=AC=E6=89=B9=E5=89=8D=E5=8E=9F=E7=8A=B6(=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E8=A1=8C=E9=9A=8F=E5=86=85=E5=AE=B9=E5=BD=92=E4=BD=8D?= =?UTF-8?q?v1.2/v1.6/v1.2),architecture.md=E6=8A=97=E7=83=AD=E9=87=8D?= =?UTF-8?q?=E8=BD=BD=E5=BF=AB=E7=85=A7=E5=8F=A5=E6=81=A2=E5=A4=8D=E5=8E=9F?= =?UTF-8?q?=E6=8E=AA=E8=BE=9E+=E6=9C=80=E8=BF=91=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E8=A1=8C=E5=A6=82=E5=AE=9E=E6=B3=A8=E8=AE=B0=E6=92=A4=E5=9B=9E?= =?UTF-8?q?;=E6=9C=AC=E6=96=87=E6=A1=A3=E6=89=B9=E5=87=80=E6=95=88?= =?UTF-8?q?=E6=9E=9C=3D=E4=B8=BB=E8=A7=92=E8=B4=A6=E4=B8=89=E4=BB=B6?= =?UTF-8?q?=E4=B8=8E=E5=88=B7=E6=96=B0=E8=B4=A6=E4=BB=B6=E8=A1=A5=E7=99=BB?= =?UTF-8?q?=E8=AE=B0+MetaProgression=E8=A1=A5=E8=A1=8C+=E5=86=BB=E7=BB=93?= =?UTF-8?q?=E8=AE=A1=E6=95=B0=E6=91=98=E9=99=A4+CurioStop/RunLedger?= =?UTF-8?q?=E6=97=A7=E6=8C=87=E7=A7=B0=E8=AE=A2=E6=AD=A3(architecture.md?= =?UTF-8?q?=20v1.32);=20=E6=96=87=E6=A1=A3=E5=9F=9F=E9=97=B8=E5=85=A8?= =?UTF-8?q?=E7=BB=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../engineering/architecture/architecture.md | 4 ++-- design/gdd/systems/战斗循环/战斗结算.md | 6 +++--- design/gdd/systems/排雷循环/棋盘生成.md | 4 ++-- design/gdd/systems/表现与支撑/数据配置.md | 18 +++++++++++------- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/design/engineering/architecture/architecture.md b/design/engineering/architecture/architecture.md index e2ff7478..4fc7fcb2 100644 --- a/design/engineering/architecture/architecture.md +++ b/design/engineering/architecture/architecture.md @@ -3,7 +3,7 @@ ## 文档状态 - 版本:1.32 -- 最近更新:2026-11-03(架构审查 5.2 文档漂移订正——主角账三件与刷新账件四行补登记替代失效的 HeroLedger 行、MetaProgression 基础层补登记行(四 Autoload 唯一跨 Autoload 依赖件)、拆件定稿节冻结计数摘除(活体清单不冻结计数)、CurioStop 行落账指称随拆件改指;沿革查 git) +- 最近更新:2026-11-03(架构审查 5.2 文档漂移订正——主角账三件与刷新账件四行补登记替代失效的 HeroLedger 行、MetaProgression 基础层补登记行(四 Autoload 唯一跨 Autoload 依赖件)、拆件定稿节冻结计数摘除(活体清单不冻结计数)、CurioStop 行落账指称随拆件改指;EC8 热重载规格经用户裁决保留原状(实装排期另立待办条目)、本批一度摘除已撤回,本文「抗热重载」快照句随规格保留;沿革查 git) - 引擎:Godot 4.7.2-stable(GDScript 单语言;2026-09-07 锁定) - 评审模式:solo(`review-mode.txt`,2026-09-12 用户拍板——TD/LP 门禁按 solo 跳过,用户授权架构产出自主推进、迭代期回调) - 覆盖 GDD:现行全集(根索引=`design/gdd/02-系统清单.md`,文档树构成以根索引为准) @@ -413,7 +413,7 @@ CJK 字体随包发行并设为 theme 默认字体——运行时默认字体无 | 各系统 → D2 | ConfigDB 类型化属性单点读取 | 禁绕过 ConfigDB load 表、禁缓存副本、禁玩法数值字面量、禁 randomize()/自建 RNG | 校验双通道 + fail-fast 致命 | | A1 → A2 | Board 产物 class_name 数据契约 | install 四不变式校验(violation = 拒绝 + 五类诊断枚举) | 生成期合法性闸(R₀≠S / clearable / min_safe) | | A1 ↔ B1 | attempt 边界非 scope 事件;actuals p10 为对账输入(非 target 参数) | 编排不把重试当取号 | 生成期指标集输出(实测可推理率 / 实际雷数与安全格数 / 重试次数 / 降级与非法产物标记) | -| B4 → B3 | buff 类经 B1 调 apply_effect(B4 零跨系统读、零直接接口) | 满层拒绝 = 零兑付 + 明细行(无折算) | 授予时数值快照(授予时定格) | +| B4 → B3 | buff 类经 B1 调 apply_effect(B4 零跨系统读、零直接接口) | 满层拒绝 = 零兑付 + 明细行(无折算) | 授予时数值快照(抗热重载) | | B1 → D1 | [步骤流行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(基础行型+扩展行两层封闭 + 公共字段 type/source_class/origin_cell/round_index/display_name/value/highlight? + 特有字段 target/effect_id/pool_value) | 无来源行 = 断言失败;呈现侧禁按行序重演 B2 状态机 | 可回放步骤流(同种子逐行相同) | **引擎类型核验注记**:接口使用的引擎类型 = Resource / .tres(D2 全表)、RefCounted(容器类)、Signal/Callable(事件载体)、Control/CanvasLayer/Drawing(D1)、SceneTree headless 协议(测试)——均属 4.x 基线稳定面;4.7 Control 域增量(offset_transform_* 等)已在 breaking-changes.md 登记,D1 采纳前对照核实。 diff --git a/design/gdd/systems/战斗循环/战斗结算.md b/design/gdd/systems/战斗循环/战斗结算.md index 102eef72..a361cf43 100644 --- a/design/gdd/systems/战斗循环/战斗结算.md +++ b/design/gdd/systems/战斗循环/战斗结算.md @@ -1,7 +1,7 @@ # 战斗结算 > 一句话:轮末结算的编排与逐行兑现 -> 状态:已定稿(自旧体系迁移);现行为 v1.7 +> 状态:已定稿(自旧体系迁移);现行为 v1.6 ## 设计目的 @@ -284,7 +284,7 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值 崩壁冲击若击杀最后敌人,仍由本轮判定段按既有顺序判胜,不新增挖掘期即时胜利出口。换图系效果使用扩展行留痕:崩壁冲击走伤害单据,石层缓冲在受伤消费行体现减免,坑道小憩与矿道红利分别走治疗与 GP 入账记录。刷新事实来源不指向单一棋盘格,使用明细流水的专长刷新效果来源豁免,不伪造来源格。 -战斗开始按固定序列开张:初始化状态池、掷骰定敌方实际数量、生成敌人、装板并预分配资源恰一次、变异布置([地形变异](../排雷循环/地形变异.md)——棋盘设置顺序第 4 步:生成棋盘 → 打开状态初始化 → 战斗资源格设置 → 变异格设置,消费 `variant_place` 封闭流)、发开轮通知并执行开轮摇号(摇定首轮各敌本拍动作)。上一关的大奖励(如血上限提升)经战斗开始入参的覆盖值通道生效,内容归[冒险结构](../冒险循环/冒险结构.md)。 +战斗开始按固定序列开张:关上配置热重载的闸门、初始化状态池、掷骰定敌方实际数量、生成敌人、装板并预分配资源恰一次、变异布置([地形变异](../排雷循环/地形变异.md)——棋盘设置顺序第 4 步:生成棋盘 → 打开状态初始化 → 战斗资源格设置 → 变异格设置,消费 `variant_place` 封闭流)、发开轮通知并执行开轮摇号(摇定首轮各敌本拍动作)。上一关的大奖励(如血上限提升)经战斗开始入参的覆盖值通道生效,内容归[冒险结构](../冒险循环/冒险结构.md)。 举证:本节为编排流程,无计算。 @@ -294,7 +294,7 @@ EV 参考数不入正文(派生读数,需要时按判定式与现行表值 | 方向 | 系统 | 接口要点 | |---|---|---| -| 上游 | [数据配置](../表现与支撑/数据配置.md) | 结算配置表(段序、当量、封顶、甲效与护甲等级掷点参数)的承载与读取,本系统是回填责任方 | +| 上游 | [数据配置](../表现与支撑/数据配置.md) | 结算配置表(段序、当量、封顶、甲效与护甲等级掷点参数)的承载与读取,本系统是回填责任方;战斗中热重载被闸门拒绝 | | 上游 | [行动经济](../排雷循环/行动经济.md) | 轮末两字段消息的接收方;回发换图指令、结算完成与战斗结束通知;挖掘期刷新经它扣费;五条经济契约的对账责任方 | | 上游 | [排雷玩法](../排雷循环/排雷玩法.md) | 订阅其三事件流(挖开格、封印判定、轮次结束);换图时调用装板与退役 | | 上游 | [棋盘生成](../排雷循环/棋盘生成.md) | 换图时调用其生成接口 | diff --git a/design/gdd/systems/排雷循环/棋盘生成.md b/design/gdd/systems/排雷循环/棋盘生成.md index 21b22ef4..9559015d 100644 --- a/design/gdd/systems/排雷循环/棋盘生成.md +++ b/design/gdd/systems/排雷循环/棋盘生成.md @@ -1,7 +1,7 @@ # 棋盘生成 > 一句话:棋盘怎么生成、怎么保证可推理可清图 -> 状态:已定稿(自旧体系迁移);现行为 v1.3 +> 状态:已定稿(自旧体系迁移);现行为 v1.2 ## 设计目的 @@ -61,7 +61,7 @@ ④ 产出上报 ─── 交出棋盘 + 生成期指标集 ``` -生成期间的每一次随机取数——布雷、重试——都从本图专属的一条"棋盘生成随机流"按固定顺序取:一张图只开一条流、用到底,重试不开新流;流之外零随机,全局随机函数一律禁用。参数行开始时一次快照。管线本身无状态——这些合起来就是"同种子同参数必产同图"的根基。(变异布置不消费本流——其取数走专用 variant_place 流,归战斗结算 布置段。) +生成期间的每一次随机取数——布雷、重试——都从本图专属的一条"棋盘生成随机流"按固定顺序取:一张图只开一条流、用到底,重试不开新流;流之外零随机,全局随机函数一律禁用。参数行开始时一次快照,配置表中途热重载不影响进行中的生成。管线本身无状态——这些合起来就是"同种子同参数必产同图"的根基。(变异布置不消费本流——其取数走专用 variant_place 流,归战斗结算 布置段。) 各阶段的失败都有明确语义,全部失败路径都不让玩家卡死(本节为纯流程规则,无计算;数值与校验式见后续各节): diff --git a/design/gdd/systems/表现与支撑/数据配置.md b/design/gdd/systems/表现与支撑/数据配置.md index d63d89ae..eb46fa93 100644 --- a/design/gdd/systems/表现与支撑/数据配置.md +++ b/design/gdd/systems/表现与支撑/数据配置.md @@ -1,7 +1,7 @@ # 数据配置 > 一句话:数值表与单一事实源管线 -> 状态:已定稿(自旧体系迁移);现行为 v1.3 +> 状态:已定稿(自旧体系迁移);现行为 v1.2 ## 设计目的 @@ -19,7 +19,7 @@ |---|---| | 全部数值表的结构与数据 | 表结构类(声明每列的类型、取值域与默认值)与数据文件成对交付;结构先行,数值由各回填责任方回填 | | 全局读取口与随机服务 | 两个进程级单例:类型化读取口与统一随机流服务 | -| 加载与校验管线 | 启动加载、fail-fast 校验 | +| 加载、校验与热重载管线 | 启动加载、fail-fast 校验、调试构建热重载的状态管理 | | 进度坐标查行 | 进度键表(跟着冒险进度成长的表)按(关卡序号 × 节点深度)两维坐标解析取行 | | 表清单与对账 | 表路径固定、清单封闭;表实与 schema 声明逐字段对账 | @@ -46,7 +46,7 @@ 单一事实源(本文含义:每个玩法数值只有一处权威载体,其余一律引用它)落到两条禁令上。第一,玩法代码零数值字面量:凡是设计师要调的数字,只存在于 data/tables/ 下的数据表里,代码里写死玩法数值即评审阻塞项。 -第二,取数只走一个口:全部系统经全局读取口的类型化属性读数(读出来就是带类型的值,例如每轮行动点就是行动经济表里那个整数字段),禁止绕过它自己加载表文件或长期缓存副本——副本绕过校验,不在单一事实源管线内。 +第二,取数只走一个口:全部系统经全局读取口的类型化属性读数(读出来就是带类型的值,例如每轮行动点就是行动经济表里那个整数字段),禁止绕过它自己加载表文件或长期缓存副本——副本绕过校验,热重载换新值时它也不知情。 表结构与数据成对交付:结构定义先行(每个字段带类型、取值域与默认值),本系统先建齐全部占位表,具体数值由回填责任方按其系统文档回填——先有格子,后填数字。表结构零界面依赖:本系统代码不引用任何界面类,无窗口的命令行模式(headless)下也能跑完整战斗,自动化测试才有载体。 @@ -109,7 +109,7 @@ └─ 任一错误 ──▶ 输出错误清单,致命中止 ``` -加载与校验在任何构建形态一律致命:任一表加载或校验失败,输出错误清单并致命中止——fail-fast 全域统一,无软着陆例外。随机服务的状态线独立于表加载:加载成败都不触碰主种子与计数器。 +热重载(不重启进程、当场重新加载表文件的调试手段,仅调试构建)单独一套处置:战斗进行中的重载请求被闸门拒绝(闸门由[战斗结算](../战斗循环/战斗结算.md)在战斗开始时置位、结束复位),重载校验失败时保留旧表继续运行并给出错误清单——不杀调试会话,这是全部规则里唯一的软着陆。调试构建之外,加载与校验在任何构建形态一律致命。随机服务的状态线独立于表加载:重载成败都不触碰主种子与计数器。 举证:本节为处置纪律约定,无计算。校验双通道与夹具注入为实现参照,本文不转载。 @@ -151,12 +151,13 @@ | 下游 | [敌人系统](../战斗循环/敌人系统.md) | 敌人表与主角表承载 | | 下游 | [增益状态](../战斗循环/增益状态.md) | 状态效果表承载;悬空引用校验的被指方 | | 下游 | [地图战斗资源](../战斗循环/地图战斗资源.md) | 奖励表与奖励配置表承载;reward_roll 流取号 | -| 下游 | [战斗结算](../战斗循环/战斗结算.md) | 结算表承载;encounter 流取号 | +| 下游 | [战斗结算](../战斗循环/战斗结算.md) | 结算表承载;热重载闸门置位与复位;encounter 流取号 | | 下游 | [秘宝](../跨局循环/秘宝.md) | 秘宝表承载 | | 下游 | [冒险结构](../冒险循环/冒险结构.md) | 关卡表与冒险表承载(登记现状见「待办」);主种子注入入口 | | 下游 | [难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | 难度表承载(占位);进度坐标查行的消费方 | | 下游 | [元进度](../跨局循环/元进度.md) | 元进度表占位承载 | | 下游 | [存档序列化](存档序列化.md) | 随机快照契约(主种子 + 全局取数计数器) | +| 下游 | [HUD 框架](HUD框架.md) | 调试热重载完成通知(仅调试构建) | | 外发 | 无订阅 | 本系统不订阅任何玩法事件 | ## P0 最小闭环 @@ -166,7 +167,8 @@ 3. 进程启动:逐表加载、逐表校验,错误收集后统一显示错误;全绿进入就绪态。 4. 全部系统经全局读取口读数,无第二取数路径。 5. 冒险开始注入主种子并开事件日志会话,统一流按事件取号。 -6. 无窗口冒烟脚本跑通加载、校验、取数、派生全链路,退出码 0。 +6. 调试构建热重载即改即验:战斗中被闸门拒绝,结束后手动再触发。 +7. 无窗口冒烟脚本跑通加载、校验、取数、派生全链路,退出码 0。 ## P1 / P2 后置 @@ -176,6 +178,7 @@ | P1 | 难度曲线导出工具(无窗口导出行解析矩阵供比对) | 难度审计的离线载体,[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)期交付物 | | P2 | 正式包构建的致命表现验证与调试覆盖结构性不存在验证 | 挂首次正式导出检查清单 | | P2 | 进度键表的调试覆盖行寻址语法 | 调试覆盖现只支持单行全局表字段,行寻址登记为后续扩展 | +| P2 | 编辑器内表文件热重载自动化 | 低优先,未指派 | ## 调参表 @@ -195,9 +198,10 @@ - 校验类别全覆盖:越界、文件缺失、空表、缺锚行、重复键、权重和为零、悬空引用各有一份测试夹具,逐类断言错误类别。 - 致命真的会死:任一致命夹具经正式通道加载,进程非 0 退出,而非仅"校验器能发现"。 - 黄金向量:随机派生纯函数对登记向量逐个复算相等;同输入恒同输出;同序号重复调用恒等。 -- 计数器纪律:连续取号跨模拟关卡切换,计数器单调不重置;表加载不改变主种子与计数器。 +- 计数器纪律:连续取号跨模拟关卡切换,计数器单调不重置;热重载成败都不改变主种子与计数器。 - 向上取整解析:请求无精确行时返回**不低于**请求坐标的最近行并留一条警告;请求超出最大已有行时封顶取最大行并留警告;同类警告去重;精确命中零警告。 - 越域与未播种:坐标低于合法域(关卡序号 <1、节点深度 <0)在进入解析前致命中止(Fatal 级诊断 + 进程非 0 退出,无兜底);高于最大已有行走封顶取最大行(警告留痕,不致命);未设主种子就取随机数致命中止,无默认种子兜底。 +- 热重载门:战斗中重载被拒绝且读数不变、不发通知;门未置位时新值可读且通知恰一次;校验失败保留旧表停留就绪态。 - 零字面量、零第二路径:静态扫描加人工复核确认玩法代码无数值字面量、无读取口之外的表加载、无全局随机函数调用。 - 零界面依赖:本系统代码不引用任何界面类,无窗口实跑通过(静态扫描与实跑两项合成判定)。 - 表实一致:各表结构与已锁字段和表结构声明逐字段一致。 From f35d097b43f449333d44974ea42cfb5428d2c3b8 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 3 Nov 2026 23:53:28 +0800 Subject: [PATCH 09/19] =?UTF-8?q?=E5=86=99=E5=8D=A1(=E6=9E=B6=E6=9E=84?= =?UTF-8?q?=E5=AE=A1=E6=9F=A5P2=E4=BB=A3=E7=A0=81=E9=9D=A2=E6=89=B9=C2=B7v?= =?UTF-8?q?1.1=E6=92=A4=E5=8D=A1=E4=BF=AE=E8=AE=A2=C2=B7=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E8=A3=81):=20EC8=E7=83=AD=E9=87=8D=E8=BD=BD=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=93=BE=E9=80=80=E5=BD=B9=E6=92=A4=E4=B8=8B=E2=80=94=E2=80=94?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=A3=81=E5=86=B3=E8=BF=91=E6=9C=9F=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E5=AE=9E=E8=A3=85,GDD=E8=A7=84=E6=A0=BC=E6=81=A2?= =?UTF-8?q?=E5=A4=8D=E5=8E=9F=E7=8A=B6(arch51-docs=20e614773a)=E3=80=81con?= =?UTF-8?q?fig=5Fdb=E9=97=A8=E4=B8=8Ereload+=E7=BC=96=E6=8E=92=E5=99=A8?= =?UTF-8?q?=E4=B8=A4=E8=A1=8C=E5=BC=80=E9=97=A8=E7=82=B9=E5=8E=9F=E6=A0=B7?= =?UTF-8?q?=E4=BF=9D=E7=95=99=E4=B8=BA=E5=AE=9E=E8=A3=85=E9=AA=A8=E6=9E=B6?= =?UTF-8?q?,=E5=AE=9E=E8=A3=85=E5=8E=BB=E5=90=91=3D=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=8F=A6=E7=AB=8B=E5=BE=85=E5=8A=9E=E6=9D=A1=E7=9B=AE+?= =?UTF-8?q?=E4=BB=96=E4=BC=9A=E8=AF=9D=E5=86=99=E5=8D=A1;=20=E6=9C=AC?= =?UTF-8?q?=E5=8D=A1=E6=94=B6=E6=95=9B=E4=B8=BA=E4=BB=85NODE=5FTYPES?= =?UTF-8?q?=E8=AF=8D=E8=A1=A8=E5=8D=95=E7=82=B9=E5=8C=96(=E5=AF=B9?= =?UTF-8?q?=E7=85=A7=E8=A1=A8/=E5=A5=91=E7=BA=A6/=E8=8C=83=E5=9B=B4/?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E5=8D=A1T1=E5=8D=95=E5=8D=A1/=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E5=88=86=E7=BA=A7/=E9=A2=84=E7=AE=97/=E6=8B=86?= =?UTF-8?q?=E5=88=86=E7=BA=AA=E5=BE=8B=E5=85=A8=E8=8A=82=E5=90=8C=E6=AD=A5?= =?UTF-8?q?,=E4=BC=B0=E6=97=B60.5=E2=86=920.25);=20=E5=BE=85=E5=8A=9E?= =?UTF-8?q?=E6=B8=85=E5=8D=95=E6=9D=A1=E7=9B=AEP2=E9=83=A8=E5=88=86?= =?UTF-8?q?=E8=A1=A8=E8=BF=B0=E5=90=8C=E6=AD=A5;=20pipeline=5Fgate=20PASS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../需求卡片-架构审查P2代码面批-2026-11-03.md | 102 ++++++++---------- 待办清单.md | 2 +- 2 files changed, 45 insertions(+), 59 deletions(-) diff --git a/reports/需求卡片-架构审查P2代码面批-2026-11-03.md b/reports/需求卡片-架构审查P2代码面批-2026-11-03.md index e0f61333..5dfbc0bd 100644 --- a/reports/需求卡片-架构审查P2代码面批-2026-11-03.md +++ b/reports/需求卡片-架构审查P2代码面批-2026-11-03.md @@ -1,52 +1,50 @@ # 需求卡片:架构审查 P2 代码面批(2026-11-03) -来源:待办清单「架构审查优化讨论——全库架构审计读数的逐条裁决与整改分批(2026-10-29 登记,来源=审计发现)」条目 P2 部分(**唯一事实源**:reports/审计-全库架构审查-2026-10-29.md §5.2 EC8 项+§5.3 NODE_TYPES 项+2026-11-03 设计讨论会话用户授权〔实现层事项按代码规则与架构文档决策——EC8 退役依用户总判据 3「死代码不保留」2026-11-02 先例〕;GDD 侧规格退役凭据=arch51-docs worktree 提交 63fc3e74〔数据配置.md v1.3/战斗结算.md v1.7/棋盘生成.md v1.3〕)。 -状态:已写卡(v1.0,2026-11-03 成文)。改动面:游戏代码(含随逻辑写/改的测试代码)。 +来源:待办清单「架构审查优化讨论——全库架构审计读数的逐条裁决与整改分批(2026-10-29 登记,来源=审计发现)」条目 P2 部分(**唯一事实源**:reports/审计-全库架构审查-2026-10-29.md §5.3 NODE_TYPES 项+2026-11-03 设计讨论会话用户授权〔实现层事项按代码规则与架构文档决策〕;热重载侧经用户裁决撤卡——规格保留原状、死开关代码保留为将来实装骨架,实装去向=用户另立待办条目+后续实装卡〔他会话写卡〕)。 +状态:已写卡(v1.1,2026-11-03 修订——原 R1〔EC8 热重载代码链退役〕经用户裁决撤下,本卡收敛为仅 NODE_TYPES 词表单点化)。改动面:游戏代码(含随逻辑写/改的测试代码)。 ## 1. 目标与完成定义 -**这批做什么**:两处零行为变更的代码面退役与单点化——审计 §5.2/§5.3 的 P2 代码遗留: +**这批做什么**:一处零行为变更的词表单点化——审计 §5.3 的 P2 代码遗留: | # | 对象 | 现状 | 终态 | |---|---|---|---| -| R1 | EC8 热重载死链 | `config_db.gd` 门标志+两方法+两诊断(:45/:174-186);`battle_orchestrator.gd` 两处开门点(:272/:633);`reload()` 全仓零调用方、走 `load()` 命中引擎资源缓存拿不到磁盘新值——门后入口死(GDD 侧规格已随文档批退役) | 八处整段删除;配置库公开面 8→6;诊断状态机零触碰(删除面全部在 reload 体内) | -| R2 | NODE_TYPES 词表双份 | `node_map_generator.gd:10` 与 `level_table.gd:11` 各持一份(内容同、序不同);生成器 :166 校验自产节点、schema :78 校验表行——校验双活、词表双写 | 词表单点归 schema(`LevelTable.NODE_TYPES`),生成器删本地副本改 class_name 直引;两处校验语义零变化(`.has()` 只判成员、序无关) | +| R1 | NODE_TYPES 词表双份 | `node_map_generator.gd:10` 与 `level_table.gd:11` 各持一份(内容同、序不同);生成器 :166 校验自产节点、schema :78 校验表行——校验双活、词表双写 | 词表单点归 schema(`LevelTable.NODE_TYPES`),生成器删本地副本改 class_name 直引;两处校验语义零变化(`.has()` 只判成员、序无关) | -**什么状态算完**:八处删除与词表改指落码、各有第 8 节对照表配对的验收断言在当轮真实跑批中通过;零行为变更证明=既有套件零转红(config_db_resolver/node_map_determinism/battle_settlement/冒烟)+结构性 sweep 恒零(第 8 节 V2/V3);代码域闸全绿;两份 reports/ 产出物(实现报告+反哺点清单)写齐。 +**不收件(热重载侧,2026-11-03 用户裁决)**:`config_db.gd` 门标志与两方法、`battle_orchestrator.gd` 两行开门点**原样保留**——热重载规格已在设计文档保留原状(arch51-docs 提交 e614773a 撤回本批一度摘除),代码为将来实装骨架;实装需求卡片由用户另立待办条目后于他会话编写,本卡零触碰。 -**排序义务**:本卡实现排队在 reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md 之后——battle_orchestrator.gd 同文件(5.1 卡重写 `_init` 与三调用点,本卡删 :272/:633 两行;后卡行号以 grep 符号锚定位)。 +**什么状态算完**:词表改指落码、第 8 节对照表配对的验收断言在当轮真实跑批中通过;零行为变更证明=既有套件零转红(node_map_determinism/关卡表校验链/冒烟)+结构性 sweep 恒零(第 8 节 V1/V2);代码域闸全绿;两份 reports/ 产出物(实现报告+反哺点清单)写齐。 + +**排序义务**:本卡实现排队在 reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md 之后——battle_orchestrator.gd 虽不再被本卡触碰,排序惯例照旧(同批架构审查卡顺次实现)。 ## 2. 设计事实源 -- **审计读数**:`reports/审计-全库架构审查-2026-10-29.md` §5.2 第三行(EC8:`ConfigDb.reload()` 全仓零调用方、缓存命中拿不到磁盘新值、门被真实开合但门后入口死)+§5.3(NODE_TYPES 词表双份)。 -- **裁决凭据**:2026-11-03 设计讨论会话用户授权(实现层事项按代码规则与架构文档决策)+用户总判据 3「死代码不保留」(2026-11-02 裁,3.1+3.2 批死效果通道同款判法先例)。 -- **GDD 侧已闭合**:arch51-docs 提交 63fc3e74——数据配置.md v1.3(热重载规格八处摘除、软着陆例外消失=fail-fast 全域统一)、战斗结算.md v1.7(开张序列去关门步)、棋盘生成.md v1.3(热重载从句删)。本卡只收代码面。 -- **架构登记**:`design/engineering/architecture/architecture.md` v1.32——:88 ConfigDB 行(公开面 8 现态登记)、:386-387 战斗序列现态、:123 battle_orchestrator 行 `set_reload_gate` 指称。 +- **审计读数**:`reports/审计-全库架构审查-2026-10-29.md` §5.3(NODE_TYPES 词表双份)。 +- **裁决凭据**:2026-11-03 设计讨论会话用户授权(实现层事项按代码规则与架构文档决策)+热重载侧撤卡裁决(规格保留、代码保留、实装另卡)。 +- **架构登记**:`design/engineering/architecture/architecture.md`——:119 行「NODE_TYPES 词表双份」表述随本卡单点化由反哺点订正。 ## 3. 现状事实(2026-11-03 master 工作区实查,基点 ab5d75a2;开工自行复核) -- **EC8 代码链八处**:config_db.gd:45(`var _reload_gate := false`——类变量第 9 个声明位);:174-186(注释行+`set_reload_gate` :176-177+`reload()` :180-186——内含 `push_diag("warning","reload_gated",...)` 与 `push_diag("debug","config_reloaded",...)` 两诊断与 `load_tables("res://data/tables", false)` 调用);battle_orchestrator.gd:272(begin_battle 序内 `db.set_reload_gate(true)`)与 :633(battle_over 清理序内 `db.set_reload_gate(false)`)。全仓 `reload_gated`/`config_reloaded`/`EC8` 字符串在 config_db.gd 之外零命中(grep 实核——测试/呈现/模拟/探针四层全零);`reload()` 调用方全仓零命中;tests 对 reload/热重载零引用。`load_tables` 本体(:131-159 一带)被启动加载与 resolver 装配真实消费——**只删门与 reload,load_tables 零触碰**。 +- **热重载侧(不收件,保留原状)**:config_db.gd:45(`_reload_gate`)+:174-186(`set_reload_gate`/`reload`)+battle_orchestrator.gd:272/:633(两行开门点)——零触碰;实装排期归用户另立待办条目+后续实装卡。 - **NODE_TYPES 双份**:`core/node_map_generator.gd:10`(`["battle", "boss", "reward", "rest", "shop"]`)与 `data/schemas/level_table.gd:11`(`["battle", "reward", "rest", "boss", "shop"]`+注释「关卡节点地图 v2.1」);消费点=node_map_generator.gd:166(`NODE_TYPES.has(String(n["type"]))`——生成器自产节点枚举校验)与 level_table.gd:78(表行加载校验)。全库第三处引用零命中(grep 实核——tests/sim/probe 全零)。两处消费均为 `.has()` 成员判定,词表序不参与行为(内容集相同)。 - **闸面现状**:S3(core 禁表加载)对 schema class_name 直引是豁免面(warning 级人工复核口径,static_scan.sh S3 注释「schema class_name 直引豁免」)——生成器改引 `LevelTable.NODE_TYPES` 落在既有豁免形态内(同款先例=config_db 持 BoardGenTable 等四域容器);零闸件改动。 -- **S13 预算**:config_db 公开方法 8(删 set_reload_gate/reload → 6)、类变量 10(删 `_reload_gate` → 9);node_map_generator 公开面与类变量零变化(删常量不涉成员账);battle_orchestrator 15 贴顶件零变化(删两行语句不涉成员)。gdstyle 基线(tools/gdstyle_baseline.txt)对本批触件零登记键(config_db/node_map_generator/battle_orchestrator 均无登记值)。 +- **S13 预算**:node_map_generator 公开面与类变量零变化(删常量不涉成员账)。gdstyle 基线(tools/gdstyle_baseline.txt)对本卡触件零登记键。 ## 4. 设计契约(违反即返工红线) -- 🔴 **零行为变更**:R1 删除面全部为死代码(门标志唯一消费者 reload 自身零调用方);R2 词表 `.has()` 判定集相同——两需求的零变更证明=既有套件零转红+同种子确定链零漂移(node_map_determinism 全绿)。RNG 封闭流、明细行协议、诊断状态机、存档与断点链零触碰。 -- 🔴 **R1 删除边界**:只删 `_reload_gate` 成员+`set_reload_gate`+`reload()`+编排器两行开门点;`load_tables`/`push_diag`/诊断状态机/其余公开面零触碰;禁留兼容别名、禁留转发壳、禁注释化残段(第 13 节全款适用)。 -- 🔴 **R2 单点方向**:词表唯一落点=`data/schemas/level_table.gd`(表行校验 owner);生成器删本地 `const NODE_TYPES`,:166 改 `LevelTable.NODE_TYPES.has(String(n["type"]))`——core→data/schemas 前向边,schema class_name 直引(S3 豁免面在案形态);禁反向(schema 引 core);禁把词表搬进第三处(词表唯一落点不可迁)。 -- 🔴 **fail-fast 不破**:删除不引入任何软回退;配置加载校验路径零改动。 +- 🔴 **零行为变更**:词表 `.has()` 判定集相同——零变更证明=既有套件零转红+同种子确定链零漂移(node_map_determinism 全绿)。RNG 封闭流、明细行协议、诊断状态机、存档与断点链零触碰。 +- 🔴 **R1 单点方向**:词表唯一落点=`data/schemas/level_table.gd`(表行校验 owner);生成器删本地 `const NODE_TYPES`,:166 改 `LevelTable.NODE_TYPES.has(String(n["type"]))`——core→data/schemas 前向边,schema class_name 直引(S3 豁免面在案形态);禁反向(schema 引 core);禁把词表搬进第三处(词表唯一落点不可迁)。 +- 🔴 **fail-fast 不破**:改动不引入任何软回退;配置加载校验路径零改动。 - 🔴 **测试纪律**:禁变异类测试、禁撤销类取证;禁删断言/放宽阈值(第 8 节申报清单之外零删改)。 ## 5. 范围边界 -**收件**=R1 八处删除+R2 词表单点化+两件新 sweep 测试+既有套件回归确认。 +**收件**=R1 词表单点化+一件新 sweep 测试+既有套件回归确认。 **不收件**(去向已指认): -- architecture.md :88 公开面 8→6/类变量 10→9、:123 行 `set_reload_gate` 指称、:386-387 战斗序列两行——**反哺点清单承载**(实现批禁写 design/,第 6 节)。 -- GDD 侧热重载规格——已随文档批退役(63fc3e74),本卡零 GDD 触碰。 +- 热重载全侧(config_db 门与 reload、编排器两行开门点、GDD 规格)——原样保留,实装去向=用户另立待办条目+后续实装卡;本卡零触碰。 +- architecture.md :119 行「NODE_TYPES 词表双份」表述——反哺点清单承载(实现批禁写 design/,第 6 节)。 - 闸面缺口(S1/S2/S9/S13 扫描面扩 sim/probe/tests、S8 目录域)与 S13 三处豁免存废——审计 P1 项,**不在本卡**(待办清单条目未闭合余项,后续讨论段)。 -- `ConfigDb.reload` 的诊断字符串(reload_gated/config_reloaded)随方法体整删——诊断状态机其余类别零触碰。 ## 6. 关联文档同步面 @@ -54,8 +52,8 @@ | 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务(反哺点清单逐条承载) | |---|---|---| -| design/engineering/architecture/architecture.md | :88 ConfigDB 行「公开面 8(…set_reload_gate/reload)」→ 6、类变量 10→9;:123 battle_orchestrator 行消费依赖「D2 SettlementTable + set_reload_gate」→ 去 set_reload_gate 指称;:386-387 战斗序列「set_reload_gate(true)→」「→ set_reload_gate(false)」两段删除;node_map_generator 相关行如有词表双份表述随 R2 订正(写卡期 grep「NODE_TYPES|词表」复核——现登记 :119 行「各持一份 NODE_TYPES 词表」随单点化删句) | 反哺点清单逐条列行号与改后登记内容——**机械面文档禁直改** | -| design/gdd/systems/表现与支撑/数据配置.md | 无陈述变化(v1.3 已退役全部热重载规格——零反哺确认行) | 反哺点清单写「零反哺」确认行 | +| design/engineering/architecture/architecture.md | :119 行「各持一份 NODE_TYPES 词表(内容同、顺序不同)」表述随单点化删句、改「词表单点归 LevelTable」 | 反哺点清单逐条列行号与改后登记内容——**机械面文档禁直改** | +| design/gdd/systems/表现与支撑/数据配置.md | 无陈述变化(热重载规格保留原状——零反哺确认行) | 反哺点清单写「零反哺」确认行 | | 术语表 | 无新术语 | 确认行「零新增术语」 | (机检口径:本表同步义务格无一条写「随批」。) @@ -68,11 +66,9 @@ ``` core 层 - game/core/config_db.gd 【非行为 R1】:45 成员删+:174-186 门与 reload 整段删(公开面 8→6、类变量 10→9) - game/core/battle_orchestrator.gd 【非行为 R1】:272/:633 两行删 - game/core/node_map_generator.gd 【非行为 R2】:10 本地词表删+:166 改 LevelTable.NODE_TYPES.has(...) + game/core/node_map_generator.gd 【非行为 R1】:10 本地词表删+:166 改 LevelTable.NODE_TYPES.has(...) 测试件(随逻辑写/改) - tests/unit/core/encapsulation_p2_sweep_test.gd 【非行为 R1–R2·新增】两处结构性零命中扫描(非空前置+正锚) + tests/unit/core/encapsulation_p2_sweep_test.gd 【非行为 R1·新增】结构性零命中扫描(非空前置+正锚) tests/run_all.gd 【非行为】manifest +1 行(sweep) 文档件 game/tests/README.md 写卡段判断=零编辑(第 8 节能力行判断依据)——实现批禁写,批末只核对能力名引用一致 @@ -80,29 +76,21 @@ core 层 --- -**T1 EC8 死链退役**(估时 0.25 工作日;区间 0.25–0.5) -取用:无(本卡起点)。产出:R1 八处清零+sweep R1 组绿。 - -- [ ] 核对实现排序在案:5.1 卡(含 battle_orchestrator 触面)未合回则本批不开工;:272/:633 现址复核(行号漂移以 `db.set_reload_gate` 符号锚定位,漂移即记录进实现报告,禁改判据) -- [ ] config_db.gd::45 `_reload_gate` 成员删;:174-186 整段删(注释行+两方法+两诊断);删除后 grep 自查 `reload` 于本文件仅剩注释性零命中(load_tables 文档注释如有 reload 字样一并订正) -- [ ] battle_orchestrator.gd::272 行删(begin_battle 序内——`_damage.set_hero_ac_override(...)` 行之后);:633 行删(battle_over 清理序内——`action_economy.notify_combat_end()` 行之后);两删除点上下语句序零变化 -- [ ] 新增 tests/unit/core/encapsulation_p2_sweep_test.gd(extends SceneTree+Kit.check 主通道,全类型标注;源 token 扫描手法沿 encapsulation_sweep_test.gd〔5.1 卡新增件〕先例)R1 组:①config_db.gd 非空+含 `class_name ConfigDb` 正锚+`set_reload_gate|_reload_gate|func reload|reload_gated|config_reloaded` 全文零命中〔架构P2 V1〕;②battle_orchestrator.gd 非空+`set_reload_gate` 零命中〔架构P2 V2〕——两组均带扫描面非空前置 -- [ ] 孤立验证:新 sweep 单件先跑绿(含改前红态确认——sweep 对未删码当轮命中即红,属断言对现状的正当判红,非变异测试);随后 config_db_resolver_test 全套+battle_settlement 套件+冒烟零转红 -- [ ] run_all.gd manifest 追加 1 行:encapsulation_p2_sweep_test(expect 0,注记「R1–R2 结构性零命中扫描〔架构P2〕」) - -**T2 NODE_TYPES 单点化+批收口**(估时 0.25 工作日;区间 0.25–0.5) -取用:T1 sweep 骨架。产出:R2 清零+批收口两件。 +**T1 NODE_TYPES 单点化+批收口**(估时 0.25 工作日;区间 0.25–0.5) +取用:无(本卡起点)。产出:R1 清零+sweep 绿+批收口两件。 +- [ ] 核对实现排序在案:5.1 卡(含 battle_orchestrator 触面)未合回则本批不开工 - [ ] node_map_generator.gd::10 本地 `const NODE_TYPES` 删;:166 改 `if not LevelTable.NODE_TYPES.has(String(n["type"])):`——头注如有词表自述随改 -- [ ] sweep 测试 R2 组:③node_map_generator.gd 非空+`^const NODE_TYPES` 零命中+`LevelTable.NODE_TYPES.has(` 正锚〔架构P2 V3〕;④全仓 .gd 生产面(core/data/presentation)`NODE_TYPES :=` 定义恰好 1 处且落 data/schemas/level_table.gd〔架构P2 V4〕 -- [ ] 孤立验证:node_map_determinism_test 全套绿(生成链同种子逐位——R2 零行为变更主证)+关卡表加载路径(level_table 校验活检查)经既有套件覆盖零转红 -- [ ] **实现报告** `reports/iter-实现报告-<日期>.md`:各卡状态+S13 键改前改后对账(config_db 公开 8→6/类变量 10→9 现场读数)+实现决定记录 -- [ ] **反哺点清单** `reports/iter-反哺点-<日期>.md`:第 6 节同步面逐条落点(architecture.md 四处、GDD/术语确认行) +- [ ] 新增 tests/unit/core/encapsulation_p2_sweep_test.gd(extends SceneTree+Kit.check 主通道,全类型标注;源 token 扫描手法沿 encapsulation_sweep_test.gd〔5.1 卡新增件〕先例)断言组:①node_map_generator.gd 非空+`^const NODE_TYPES` 零命中+`LevelTable.NODE_TYPES.has(` 正锚〔架构P2 V1〕;②全仓 .gd 生产面(core/data/presentation)`NODE_TYPES :=` 定义恰好 1 处且落 data/schemas/level_table.gd〔架构P2 V2〕——两组均带扫描面非空前置 +- [ ] 孤立验证:新 sweep 单件先跑绿;node_map_determinism_test 全套绿(生成链同种子逐位——R1 零行为变更主证)+关卡表加载路径(level_table 校验活检查)经既有套件覆盖零转红+冒烟零转红 +- [ ] run_all.gd manifest 追加 1 行:encapsulation_p2_sweep_test(expect 0,注记「R1 结构性零命中扫描〔架构P2〕」) +- [ ] **实现报告** `reports/iter-实现报告-<日期>.md`:各卡状态+S13 键改前改后对账(node_map_generator 现场读数)+实现决定记录 +- [ ] **反哺点清单** `reports/iter-反哺点-<日期>.md`:第 6 节同步面逐条落点(architecture.md :119 一处、GDD/术语确认行) - [ ] 批末核对:README 能力名引用一致(本卡零编辑);独立验收审计(第 8 节末)未过不合并;.uid 收口=`--editor --quit` 一次后确认新测试件 .uid 随批提交 ### 估时汇总 -T1 0.25|T2 0.25。区间合计 0.5–1.0 工作日;**精确汇总 0.5 工作日**(超 1 工作日=超卡面估时域,须用户确认后方可续批)。 +T1 0.25。区间合计 0.25–0.5 工作日;**精确汇总 0.25 工作日**(超 0.5 工作日=超卡面估时域,须用户确认后方可续批)。 ## 8. 验证闸(改动—验收对照表) @@ -110,33 +98,31 @@ T1 0.25|T2 0.25。区间合计 0.5–1.0 工作日;**精确汇总 0.5 工作 | 需求点 | 改动(文件:行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 | |---|---|---|---|---|---|---| -| R1 EC8 死链退役 | config_db :45/:174-186 删+battle_orchestrator :272/:633 删 | encapsulation_p2_sweep_test R1 组〔架构P2 V1/V2〕;config_db_resolver_test 既有全套(加载/校验/解析面零转红);battle_settlement 套件+冒烟零转红(战斗序列少两行后全链逐位) | 单元+集成 | `ConfigDB.load_tables()`(启动加载)→`BattleOrchestrator.begin_battle()`→battle_over 全链 | 源码五符号零命中(非空前置);解析/加载/结算行为面零漂移 | 既有:加载期违规表拒绝:跨表悬空/计数器前缀/真视窄域/效果类型出域;既有:轮内流与结算五段全序 | -| R2 NODE_TYPES 单点化 | node_map_generator :10 删+:166 改指 | encapsulation_p2_sweep_test R2 组〔架构P2 V3/V4〕;node_map_determinism_test 既有全套(同种子同参数必产同图逐位) | 单元+集成 | `LevelRunner` 关卡推进→节点图生成真实入口;`LevelTable` 表行加载校验 | 词表定义唯一落点(正锚计数=1);生成链同种子逐位同 | 既有:节点图生成合法性与同种子复现;既有:起关/选路/断点重生成同图(集成) | +| R1 NODE_TYPES 单点化 | node_map_generator :10 删+:166 改指 | encapsulation_p2_sweep_test〔架构P2 V1/V2〕;node_map_determinism_test 既有全套(同种子同参数必产同图逐位) | 单元+集成 | `LevelRunner` 关卡推进→节点图生成真实入口;`LevelTable` 表行加载校验 | 词表定义唯一落点(正锚计数=1);生成链同种子逐位同 | 既有:节点图生成合法性与同种子复现;既有:起关/选路/断点重生成同图(集成) | -**零行为改动面的证据义务**:本卡两行均为非行为改动——每行零变更证明=既有套件零转红+sweep 恒零+(R2)确定性链逐位。能力行全部「既有」、零新增——判断依据:零行为变更=玩家可观测能力面零变化;能力清单零编辑(批末核对义务在 T2)。 +**零行为改动面的证据义务**:本卡一行均为非行为改动——零变更证明=既有套件零转红+sweep 恒零+确定性链逐位。能力行全部「既有」、零新增——判断依据:零行为变更=玩家可观测能力面零变化;能力清单零编辑(批末核对义务在 T1)。 **闸口径**:重闸=`tools/run_all_gates.sh` 按本批改动域选档(改动含 game/ 下非 .md 行为载体 → `--code`);所选域全绿才合并。卡内不写死闸件名单。回归措辞:里程碑卡出口跑一次全套闸;卡内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套。 -**测试削弱申报**:零条——本批零删改既有断言(grep 实核:tests 对 reload/EC8/NODE_TYPES 零引用,无断言需要迁移)。 +**测试削弱申报**:零条——本批零删改既有断言(grep 实核:tests 对 NODE_TYPES 零引用,无断言需要迁移)。 -**独立验收审计**:入口=批末 T2 后、合并前;报告=`reports/iter-验收审计-<日期>.md`;由没参与实现的会话或子代理执行,核对:对照表逐行断言真实存在且当轮通过、sweep 非空前置在案、零删改核对、S13 键只降不升对账。未过不合并。 +**独立验收审计**:入口=批末 T1 后、合并前;报告=`reports/iter-验收审计-<日期>.md`;由没参与实现的会话或子代理执行,核对:对照表逐行断言真实存在且当轮通过、sweep 非空前置在案、零删改核对、S13 键只降不升对账。未过不合并。 ## 9. 异常分级 -- **L1 自救**:删除行错位一行、sweep 正则笔误、注释错字——就地改,记录进实现报告。 +- **L1 自救**:改指行错位、sweep 正则笔误、注释错字——就地改,记录进实现报告。 - **L2 记录继续**:行号 ±5 行内漂移(grep 符号锚定位后继续)。 -- **L3 停机写报告等用户**:①实现中发现 `reload()`/`NODE_TYPES` 出现卡面未登记的第三处消费面(现状事实失实=上游缺陷,禁代裁);②删除后任一既有套件转红(零行为变更契约被破=停卡,禁就地调和);③机检键与卡片契约互斥=停卡呈报,禁自造第三条路。 +- **L3 停机写报告等用户**:①实现中发现 `NODE_TYPES` 出现卡面未登记的第三处消费面(现状事实失实=上游缺陷,禁代裁);②改指后任一既有套件转红(零行为变更契约被破=停卡,禁就地调和);③机检键与卡片契约互斥=停卡呈报,禁自造第三条路。 ## 10. 代拍板白名单 - sweep 正则具体写法与断言消息措辞(尾缀〔架构P2 Vn〕与判别词保留)。 -- 删除点上下空行/注释的整理(语句序不变)。 - 逐卡内「孤立验证→出红最小单元→并入全套」执行顺序细节。 超清单的决断记入实现报告「实现决定记录」节。 ## 11. 待裁点 -**零待裁点,开工门=U0**——两处退役/单点化方向均由审计读数+用户总判据 3(死代码不保留)+2026-11-03 会话授权导出;删除边界、单点落点、T 卡分解、验收断言由写卡期实查定死(第 3/7 节)。本卡未新增备选案。 +**零待裁点,开工门=U0**——词表单点化方向由审计读数+2026-11-03 会话授权导出;热重载侧经用户裁决撤卡(规格保留、代码保留为实装骨架、实装另卡)。单点落点、T 卡分解、验收断言由写卡期实查定死(第 3/7 节)。本卡未新增备选案。 ## 12. 落位与可复用性预检 @@ -147,19 +133,19 @@ T1 0.25|T2 0.25。区间合计 0.5–1.0 工作日;**精确汇总 0.5 工作 **复用既有**:源 token 扫描手法=encapsulation_sweep_test/player_copy_sweep_test 先例;manifest 登记=run_all.gd 既有条目族;schema class_name 直引形态=config_db 域容器四先例。 -**分层与交互面**:R2 前向边 core→data/schemas=S3 豁免面在案形态(同 config_db 持表容器方向);零新增跨域路径、零新依赖;RngService 红线零触碰;Core 零 UI 红线零触碰;数值单一事实源零触碰(零表改动)。 +**分层与交互面**:R1 前向边 core→data/schemas=S3 豁免面在案形态(同 config_db 持表容器方向);零新增跨域路径、零新依赖;RngService 红线零触碰;Core 零 UI 红线零触碰;数值单一事实源零触碰(零表改动)。 ## 13. 禁为机检文本保留无效成员 -本卡为退役/收敛类卡:删除面禁留兼容别名、转发壳、注释化残段(`set_reload_gate`/`reload`/`_reload_gate` 删除后禁以任何形态残留);词表删除后生成器禁留本地副本或镜像常量。机检键与卡片契约互斥时实现段一律停卡呈报,不得自造第三条路。 +本卡为收敛类卡:词表删除后生成器禁留本地副本或镜像常量。机检键与卡片契约互斥时实现段一律停卡呈报,不得自造第三条路。 ## 14. 实现规范预算 新增 .gd 仅 1 个测试件(SceneTree 脚本,全类型标注、零公开生产面)。生产代码全部落既有件,按「存量触面一查」对账(S13 默认阈值): -- **净减件**:config_db 公开 8→6、类变量 10→9;battle_orchestrator 零成员变化(两行语句删);node_map_generator 零成员变化(常量删+一处改指)。 -- **存量触面 S13 预期**:触件三件 S13 键较现场基线只降不升(净删为主);gdstyle 基线对三件零登记键,T1 现场读数即对账基线。 +- **零成员变化件**:node_map_generator 公开面与类变量零变化(常量删+一处改指)。 +- **存量触面 S13 预期**:触件一件 S13 键较现场基线只降不升;gdstyle 基线零登记键,T1 现场读数即对账基线。 - **指标例外申报**:无。 ## 15. 拆分边界纪律 -本卡零新拆件——三触件全部架构在册既有件,只做死代码退役与词表单点化;逐件职责语句不变(config_db=加载/校验/override/诊断门面〔reload 非其现行职责——死链随批清除〕;node_map_generator=关卡节点图生成域唯一承载〔词表消费方身份不变、定义权归 schema owner〕)。单一变化原因=封装与单一事实源(死链清零、词表归一),非阈值驱动。禁凑计数袋:本卡无成员打包面。先例=3.1+3.2 批甲案死效果通道退役(EFFECT_KINDS 摘名+分支删除,用户总判据 3 同款判法)。 +本卡零新拆件——触件全部架构在册既有件,只做词表单点化;逐件职责语句不变(node_map_generator=关卡节点图生成域唯一承载〔词表消费方身份不变、定义权归 schema owner〕)。单一变化原因=单一事实源(词表归一),非阈值驱动。禁凑计数袋:本卡无成员打包面。 diff --git a/待办清单.md b/待办清单.md index cc95b5dc..e8b6d727 100644 --- a/待办清单.md +++ b/待办清单.md @@ -20,7 +20,7 @@ **2026-11-02 写卡(2026-11-03 修订闭合)**:需求卡片 reports/需求卡片-架构审查3.1+3.2整改批-2026-11-02.md(v1.2——子代理写卡+grilling 一轮 19 条折入+godot-master 式终审 4 条折入,pipeline_gate PASS,worktree 提交 2f43b81d);11 张 T 卡估时合计 8 工作日(超 10 须特批提示在卡);能力行 10 增 5 改 1 删已入 game/tests/README.md。 -**2026-11-03 P2 部分(5.1 封装+5.2 文档漂移+5.3 词表)推进**:5.1 设计闭合+已写卡——处置记录落 arch51-docs worktree、需求卡片 v1.1(godot-master 终审七项折入,pipeline_gate PASS)落 arch51-card worktree,两件随各自合回落 master 后互见;5.2 文档漂移四处归真已落档(architecture.md v1.32——HeroLedger 行拆件四件补登记/冻结计数摘除/MetaProgression 补登记行;EC8 GDD 侧规格退役=数据配置.md v1.3+战斗结算.md v1.7+棋盘生成.md v1.3,arch51-docs worktree 提交 63fc3e74,文档域闸全绿);5.3+EC8 代码面已写卡——凭据=reports/需求卡片-架构审查P2代码面批-2026-11-03.md v1.0(本条目所在 master 基点 ab5d75a2 的 archp2-card worktree,零待裁点,估时 0.5 工作日,排序在 5.1 卡后);**未闭合余项收窄**=闸面缺口(S1/S2/S9/S13 扫描面、S8 目录域)、S13 三处豁免存废、零测试点名四件、presentation 层私取面约 227 行(另开设计讨论)。 +**2026-11-03 P2 部分(5.1 封装+5.2 文档漂移+5.3 词表)推进**:5.1 设计闭合+已写卡——处置记录落 arch51-docs worktree、需求卡片 v1.1(godot-master 终审七项折入,pipeline_gate PASS)落 arch51-card worktree,两件随各自合回落 master 后互见;5.2 文档漂移归真已落档(architecture.md v1.32——HeroLedger 行拆件四件补登记/冻结计数摘除/MetaProgression 补登记行/CurioStop 与 RunLedger 旧指称订正,arch51-docs worktree 提交 63fc3e74+e614773a,文档域闸全绿);**EC8 热重载侧经用户裁决撤卡**——GDD 规格恢复原状(本批一度摘除已撤回)、config_db 门与 reload+编排器两行开门点代码原样保留为将来实装骨架,实装去向=用户另立待办条目+后续实装卡(他会话写卡);5.3 已写卡——凭据=reports/需求卡片-架构审查P2代码面批-2026-11-03.md v1.1(archp2-card worktree,仅 NODE_TYPES 词表单点化,零待裁点,估时 0.25 工作日,排序在 5.1 卡后);**未闭合余项收窄**=闸面缺口(S1/S2/S9/S13 扫描面、S8 目录域)、S13 三处豁免存废、零测试点名四件、presentation 层私取面约 227 行(另开设计讨论)。 **改动面**:文档+游戏代码+工具代码 From e9e0961c42cb8063986074517ed3136a2ae4826f Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 4 Nov 2026 00:07:42 +0800 Subject: [PATCH 10/19] =?UTF-8?q?=E5=86=99=E5=8D=A1(=E6=9E=B6=E6=9E=84?= =?UTF-8?q?=E5=AE=A1=E6=9F=A55.1=E5=B0=81=E8=A3=85=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=89=B9=C2=B7=E5=B9=B6master=E9=80=82=E9=85=8D):=20=E5=BE=85?= =?UTF-8?q?=E5=8A=9E=E6=B8=85=E5=8D=95=E5=90=88=E5=B9=B6=E8=A7=A3=E5=86=B2?= =?UTF-8?q?=E7=AA=81=E2=80=94=E2=80=94=E6=97=A7=E3=80=8C=E6=9E=B6=E6=9E=84?= =?UTF-8?q?=E5=AE=A1=E6=9F=A5=E4=BC=98=E5=8C=96=E8=AE=A8=E8=AE=BA=E3=80=8D?= =?UTF-8?q?=E6=9D=A1=E7=9B=AE=E5=B7=B2=E9=9A=8F=E7=8A=B6=E6=80=81=E6=9C=BA?= =?UTF-8?q?=E5=87=BA=E5=8F=A3=E5=88=A0=E9=99=A4,5.1=E5=87=AD=E6=8D=AE?= =?UTF-8?q?=E6=AE=B5=E8=BF=81=E5=85=A5=E6=96=B0=E3=80=8C=E6=9E=B6=E6=9E=84?= =?UTF-8?q?=E5=AE=A1=E6=9F=A5=E4=BD=99=E9=A1=B9=E3=80=8D=E4=B8=93=E6=9D=A1?= =?UTF-8?q?=E5=B9=B6=E6=8D=A2=E4=BB=A3v1.1=E5=8F=A3=E5=BE=84(=E7=BB=88?= =?UTF-8?q?=E5=AE=A1=E4=B8=83=E9=A1=B9/SlotStore=E5=8F=8D=E5=90=9121?= =?UTF-8?q?=E5=A4=84/=E4=BC=B0=E6=97=B62.875/3.1+3.2=E5=90=88=E5=9B=9E?= =?UTF-8?q?=E5=90=8E=E6=8E=92=E5=BA=8F=E5=89=8D=E7=BD=AE=E8=A7=A3=E9=99=A4?= =?UTF-8?q?);=20=E5=8D=A1=E9=9D=A2=C2=A78=E8=A1=A5test-conventions=20?= =?UTF-8?q?=C2=A78.3=E8=A6=86=E7=9B=96=E7=99=BB=E8=AE=B0=E4=B9=89=E5=8A=A1?= =?UTF-8?q?=E9=80=82=E9=85=8D(breakpoint=5Fstore/slot=5Fstore/battle=5Ffx?= =?UTF-8?q?=5Fhost=E4=B8=89=E4=BB=B6=E7=BB=8F=E5=AE=BF=E4=B8=BB=E9=93=BE?= =?UTF-8?q?=E8=A6=86=E7=9B=96=E7=94=B3=E6=8A=A5);=20pipeline=5Fgate=20PASS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md | 2 +- 待办清单.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md b/reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md index 0010a353..631675d6 100644 --- a/reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md +++ b/reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md @@ -218,7 +218,7 @@ T1 0.25|T2 1.25|T3 0.625|T4 0.375|T5 0.375。 | R5 save_manager↔SlotStore 双向公开面 | save_manager→SlotStore=slot_store +active_path/_migrate 更名公开化+save_manager 九行改址;SlotStore→SaveManagerCore=save_manager +5 公开方法/2 更名公开化+slot_store 21 处改址 | save_manager_domain_test.gd:_smoke_save+save_slot_isolation_test 既有回归;encapsulation_sweep_test `slots\._` 与 `_save\._` 双向零命中+双正锚〔封装5.1 V5〕 | 单元 | `SaveManagerCore.write_to_disk()`/`load_from_disk()`/`_ready()` 迁移口/`SlotStore.activate_slot()`(三态恢复路径——read_only/data 快照还原)/`peek_slot_summary()`(窥视委托) | 写盘/读回/迁移/激活-恢复/窥视路径逐位同(tmp+rename 原子序、零拷贝还原语义不变);save_manager 源零 `slots._`+slot_store 源零 `_save._` | 既有:存档写盘⇄读回往返保真 | | R6 config_db→三表挂载 | 三 schema +bind_resolver;config_db :157-159 改址 | config_db_resolver_test.gd 既有全套回归(_test_rowset_order_preserved/_test_row_kind_routing/_test_difficulty_clamp——resolver 注入后解析面逐位同);encapsulation_sweep_test `\._resolver =` 零命中+正锚〔封装5.1 V7〕 | 单元 | `ConfigDB.load_tables()`(装配段)→`ConfigDbResolver.resolve_*()` | 行集解析/难度 clamp 逐位同;config_db 源零 `_resolver` 直写 | 既有:行集寻址、行序保序与难度乘数 clamp | -**零行为改动面的证据义务**:本卡全部六行均为非行为改动(零行为变更批)——不设「行为改动」行;每行的零变更证明=T1 golden 同种子逐项比对(改前固化、改后全程绿)+既有套件零转红+结构性 sweep 恒零。能力行全部「既有」、零新增——判断依据:本批零行为变更=玩家可观测能力面零变化,无新能力可登记;受影响存量行的真实入口与代表用例名零变化(settle_segments_test/adventure_feats_test 文件名与其在册引用不变),故能力清单零编辑(批末核对义务在 T5)。 +**零行为改动面的证据义务**:本卡全部六行均为非行为改动(零行为变更批)——不设「行为改动」行;每行的零变更证明=T1 golden 同种子逐项比对(改前固化、改后全程绿)+既有套件零转红+结构性 sweep 恒零。能力行全部「既有」、零新增——判断依据:本批零行为变更=玩家可观测能力面零变化,无新能力可登记;受影响存量行的真实入口与代表用例名零变化(settle_segments_test/adventure_feats_test 文件名与其在册引用不变),故能力清单零编辑(批末核对义务在 T5)。**覆盖登记(test-conventions §8.3 新增 core 件覆盖登记义务,2026-11-04 并 master 后适配)**:本批触碰且曾被审计点名的三件按「经宿主链覆盖」申报——breakpoint_store=R4 行 `AdventureRunner.resume_adventure()/start_adventure()`→`write_to_disk()/load_from_disk()` 链+新增 sweep 源扫描;slot_store=R5 行 `SaveManagerCore.write_to_disk()/load_from_disk()/_ready()` 迁移口链;battle_fx_host=R1/R3 行 `begin_battle()` 全结算链;三件申报面之外零新增点名义务,meta_state_store 本卡零触碰。 **闸口径**:重闸=`tools/run_all_gates.sh` 按本批改动域选档(改动含 game/ 下非 .md 行为载体 → `--code`);所选域全绿才合并。卡内不写死闸件名单。回归措辞:里程碑卡(T 段)出口跑一次全套闸;卡内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套。 diff --git a/待办清单.md b/待办清单.md index 09cbb9b1..f322ceb4 100644 --- a/待办清单.md +++ b/待办清单.md @@ -16,9 +16,9 @@ **实况**:2026-10-29 全库架构静态审计的四组待裁余项,自「架构审查优化讨论」条目迁入(该条目的 3.1+3.2 部分已随迭代 50 卡③实现合回〔合并提交 8d3a12ec〕,余项不在本卡,按未决先迁再死迁立本条)。四组余项(审计待裁点 ④⑤⑥⑦,读数为审计时点,逐项现值以仓库为准):①守卫闸面缺口——S1/S2 随机函数扫描面止步 core+presentation(sim 4 处/probe 1 处/tests 3 处自建 RNG 不在扫)、S9 类型闸与 S13 质量闸扫描面不含 sim/probe/tests、S8 是 9 文件显式清单(缺位自检只防删改不防增);②S13 质量闸豁免存废——审计时点三处豁免常态化到最大户文件(battle_orchestrator 已随拆件批收窄,余量以闸件为准);③零测试点名四件(attune_loadout/battle_fx_host/meta_state_store/slot_store);④架构文档漂移三处(architecture.md 登记的 core/hero_ledger.gd 盘上不存在且测试断言它必须不存在、行数过期、EC8 热重载门后 ConfigDb.reload() 零调用方且走 load() 拿不到磁盘新值)。凭据:reports/审计-全库架构审查-2026-10-29.md(待裁点节)+reports/处置-架构审查3.1+3.2整改-2026-11-02.md(3.1+3.2 闭合凭据,随迭代 50 合回)。 -**缺口**:四组余项中①②③ 已裁完并落地(见下 2026-11-03 记录),还差④**架构文档漂移三处**的裁决与落文(`architecture.md` 的 HeroLedger 登记行、battle_orchestrator 行数与成员数、EC8 热重载门后 `ConfigDb.reload()` 零调用方)——属审计 §5.2/待裁点⑦,需再走一次设计讨论;同族的审计 §5.1(settlement 私有成员直取,实测 105 处)/§5.3(NODE_TYPES 词表双份)/§5.4(MetaProgression 取依赖形态)尚未登记本条,随④同批处置时一并入册。 +**缺口**:四组余项中①②③ 已裁完并落地(见下 2026-11-03 记录);④**架构文档漂移三处**的落文档由并行 worktree 批(arch51-docs——HeroLedger 行拆件四件补登记+行数冻结计数摘除+MetaProgression 补登记行)承载,随其合回销号;同族审计 §5.1 已登记(见下 2026-11-03/11-04 记录,已写卡),§5.3(NODE_TYPES 词表单点化)已写卡于并行 worktree archp2-card、§5.4(MetaProgression 登记零动作)已随 arch51-docs 落文——均随各自合回入册;presentation 层私取面约 227 行另开设计讨论,为本条最后余项。 -**2026-11-03 设计闭合+写卡(5.1 封装修复部分)**:2026-11-03 会话对审计 §5.1(settlement 段类私取编排器私有成员)完成设计讨论并扩面普查,裁决五处跨对象私有访问修复方案(settlement 七段→编排器束交付/搬家五方法/adventure_runner→BreakpointStore/save_manager→SlotStore/grant_segment→BattleFxHost+config_db→三表容器;presentation 层约 227 行另开设计讨论不在内)。凭据=reports/处置-架构审查5.1封装修复-2026-11-03.md(处置记录,与本卡并行成文)+审计报告 §5.1+architecture.md:119/:124/:137-146。需求卡片 reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md(v1.0——5 张 T 卡估时精确汇总 2.75 工作日;零行为变更批,能力清单零新增行已写明判断依据);实现排序在 3.1+3.2 卡之后(combat_segment 同文件避让)。 +**2026-11-03 设计闭合+写卡(5.1 封装修复部分,2026-11-04 并 master 后凭据换代)**:2026-11-03 会话对审计 §5.1(settlement 段类私取编排器私有成员)完成设计讨论并扩面普查,裁决五处跨对象私有访问修复方案(settlement 七段→编排器束交付/搬家五方法/adventure_runner→BreakpointStore/save_manager↔SlotStore 双向公开面/grant_segment→BattleFxHost+config_db→三表容器;presentation 层约 227 行另开设计讨论不在内)。凭据=reports/处置-架构审查5.1封装修复-2026-11-03.md(处置记录)+审计报告 §5.1+architecture.md:119/:124/:137-146。需求卡片 reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md(**v1.1**——godot-master 终审七项折入〔golden 封印步改封未揭示相邻格/三 schema 解析冒烟义务/T3 签名补注解/成员账两笔订正/harmful_adjacent 自呼随更名/现值交付口径注/SlotStore→SaveManagerCore 反向私取终审补查 21 处并入 T3〕;5 张 T 卡估时精确汇总 2.875 工作日;零行为变更批,能力清单零新增行已写明判断依据);实现排序在 3.1+3.2 卡之后——该卡已随迭代 50 合回,前置已解除(combat_segment 行号漂移按卡内 grep 锚定位预案处理)。 **改动面**:文档+游戏代码+工具代码 From 6254b5dbc1187c1e7ab6acc3e59bc2abc21491be Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 4 Nov 2026 00:09:28 +0800 Subject: [PATCH 11/19] =?UTF-8?q?=E5=86=99=E5=8D=A1(=E6=9E=B6=E6=9E=84?= =?UTF-8?q?=E5=AE=A1=E6=9F=A5P2=E4=BB=A3=E7=A0=81=E9=9D=A2=E6=89=B9=C2=B7?= =?UTF-8?q?=E5=B9=B6master=E9=80=82=E9=85=8D):=20=E5=BE=85=E5=8A=9E?= =?UTF-8?q?=E6=B8=85=E5=8D=95=E5=90=88=E5=B9=B6=E8=A7=A3=E5=86=B2=E7=AA=81?= =?UTF-8?q?=E2=80=94=E2=80=945.2/5.3=E6=8E=A8=E8=BF=9B=E6=AE=B5=E8=BF=81?= =?UTF-8?q?=E5=85=A5=E6=96=B0=E3=80=8C=E6=9E=B6=E6=9E=84=E5=AE=A1=E6=9F=A5?= =?UTF-8?q?=E4=BD=99=E9=A1=B9=E3=80=8D=E4=B8=93=E6=9D=A1=E3=80=81=E7=BC=BA?= =?UTF-8?q?=E5=8F=A3=E8=A1=8C=E6=8D=A2=E4=BB=A3(=C2=A75.1/=C2=A75.3/=C2=A7?= =?UTF-8?q?5.4=20=E5=85=A5=E5=86=8C=E7=8E=B0=E7=8A=B6+=E2=91=A3=E7=94=B1ar?= =?UTF-8?q?ch51-docs=E6=89=BF=E8=BD=BD+=E4=BD=99=E9=A1=B9=E4=BB=85?= =?UTF-8?q?=E5=89=A9presentation=E5=B1=82),=E6=9C=AA=E9=97=AD=E5=90=88?= =?UTF-8?q?=E4=BD=99=E9=A1=B9=E8=A1=A8=E8=BF=B0=E5=AF=B9=E8=B4=A6=C2=A74?= =?UTF-8?q?=E6=89=B9=E9=97=AD=E5=90=88=E7=8E=B0=E7=8A=B6;=20=E5=8D=A1?= =?UTF-8?q?=E9=9D=A2NODE=5FTYPES=E6=B6=88=E8=B4=B9=E7=82=B9=E8=A1=8C?= =?UTF-8?q?=E5=8F=B7=E6=8D=A2=E4=BB=A3:166=E2=86=92:136(=E8=BF=AD=E4=BB=A3?= =?UTF-8?q?50=E4=B8=99=E6=A1=88=E5=88=A0=E5=9F=9F=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E6=AE=B5=E5=90=8E=E5=89=8D=E7=A7=BB,grep=E5=AE=9E=E6=A0=B8);?= =?UTF-8?q?=20pipeline=5Fgate=20PASS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- reports/需求卡片-架构审查P2代码面批-2026-11-03.md | 12 ++++++------ 待办清单.md | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/reports/需求卡片-架构审查P2代码面批-2026-11-03.md b/reports/需求卡片-架构审查P2代码面批-2026-11-03.md index 5dfbc0bd..02041a6f 100644 --- a/reports/需求卡片-架构审查P2代码面批-2026-11-03.md +++ b/reports/需求卡片-架构审查P2代码面批-2026-11-03.md @@ -9,7 +9,7 @@ | # | 对象 | 现状 | 终态 | |---|---|---|---| -| R1 | NODE_TYPES 词表双份 | `node_map_generator.gd:10` 与 `level_table.gd:11` 各持一份(内容同、序不同);生成器 :166 校验自产节点、schema :78 校验表行——校验双活、词表双写 | 词表单点归 schema(`LevelTable.NODE_TYPES`),生成器删本地副本改 class_name 直引;两处校验语义零变化(`.has()` 只判成员、序无关) | +| R1 | NODE_TYPES 词表双份 | `node_map_generator.gd:10` 与 `level_table.gd:11` 各持一份(内容同、序不同);生成器 :136 校验自产节点、schema :78 校验表行——校验双活、词表双写 | 词表单点归 schema(`LevelTable.NODE_TYPES`),生成器删本地副本改 class_name 直引;两处校验语义零变化(`.has()` 只判成员、序无关) | **不收件(热重载侧,2026-11-03 用户裁决)**:`config_db.gd` 门标志与两方法、`battle_orchestrator.gd` 两行开门点**原样保留**——热重载规格已在设计文档保留原状(arch51-docs 提交 e614773a 撤回本批一度摘除),代码为将来实装骨架;实装需求卡片由用户另立待办条目后于他会话编写,本卡零触碰。 @@ -26,14 +26,14 @@ ## 3. 现状事实(2026-11-03 master 工作区实查,基点 ab5d75a2;开工自行复核) - **热重载侧(不收件,保留原状)**:config_db.gd:45(`_reload_gate`)+:174-186(`set_reload_gate`/`reload`)+battle_orchestrator.gd:272/:633(两行开门点)——零触碰;实装排期归用户另立待办条目+后续实装卡。 -- **NODE_TYPES 双份**:`core/node_map_generator.gd:10`(`["battle", "boss", "reward", "rest", "shop"]`)与 `data/schemas/level_table.gd:11`(`["battle", "reward", "rest", "boss", "shop"]`+注释「关卡节点地图 v2.1」);消费点=node_map_generator.gd:166(`NODE_TYPES.has(String(n["type"]))`——生成器自产节点枚举校验)与 level_table.gd:78(表行加载校验)。全库第三处引用零命中(grep 实核——tests/sim/probe 全零)。两处消费均为 `.has()` 成员判定,词表序不参与行为(内容集相同)。 +- **NODE_TYPES 双份**:`core/node_map_generator.gd:10`(`["battle", "boss", "reward", "rest", "shop"]`)与 `data/schemas/level_table.gd:11`(`["battle", "reward", "rest", "boss", "shop"]`+注释「关卡节点地图 v2.1」);消费点=node_map_generator.gd:136(`NODE_TYPES.has(String(n["type"]))`——生成器自产节点枚举校验)与 level_table.gd:78(表行加载校验)。全库第三处引用零命中(grep 实核——tests/sim/probe 全零)。两处消费均为 `.has()` 成员判定,词表序不参与行为(内容集相同)。 - **闸面现状**:S3(core 禁表加载)对 schema class_name 直引是豁免面(warning 级人工复核口径,static_scan.sh S3 注释「schema class_name 直引豁免」)——生成器改引 `LevelTable.NODE_TYPES` 落在既有豁免形态内(同款先例=config_db 持 BoardGenTable 等四域容器);零闸件改动。 - **S13 预算**:node_map_generator 公开面与类变量零变化(删常量不涉成员账)。gdstyle 基线(tools/gdstyle_baseline.txt)对本卡触件零登记键。 ## 4. 设计契约(违反即返工红线) - 🔴 **零行为变更**:词表 `.has()` 判定集相同——零变更证明=既有套件零转红+同种子确定链零漂移(node_map_determinism 全绿)。RNG 封闭流、明细行协议、诊断状态机、存档与断点链零触碰。 -- 🔴 **R1 单点方向**:词表唯一落点=`data/schemas/level_table.gd`(表行校验 owner);生成器删本地 `const NODE_TYPES`,:166 改 `LevelTable.NODE_TYPES.has(String(n["type"]))`——core→data/schemas 前向边,schema class_name 直引(S3 豁免面在案形态);禁反向(schema 引 core);禁把词表搬进第三处(词表唯一落点不可迁)。 +- 🔴 **R1 单点方向**:词表唯一落点=`data/schemas/level_table.gd`(表行校验 owner);生成器删本地 `const NODE_TYPES`,:136 改 `LevelTable.NODE_TYPES.has(String(n["type"]))`——core→data/schemas 前向边,schema class_name 直引(S3 豁免面在案形态);禁反向(schema 引 core);禁把词表搬进第三处(词表唯一落点不可迁)。 - 🔴 **fail-fast 不破**:改动不引入任何软回退;配置加载校验路径零改动。 - 🔴 **测试纪律**:禁变异类测试、禁撤销类取证;禁删断言/放宽阈值(第 8 节申报清单之外零删改)。 @@ -66,7 +66,7 @@ ``` core 层 - game/core/node_map_generator.gd 【非行为 R1】:10 本地词表删+:166 改 LevelTable.NODE_TYPES.has(...) + game/core/node_map_generator.gd 【非行为 R1】:10 本地词表删+:136 改 LevelTable.NODE_TYPES.has(...) 测试件(随逻辑写/改) tests/unit/core/encapsulation_p2_sweep_test.gd 【非行为 R1·新增】结构性零命中扫描(非空前置+正锚) tests/run_all.gd 【非行为】manifest +1 行(sweep) @@ -80,7 +80,7 @@ core 层 取用:无(本卡起点)。产出:R1 清零+sweep 绿+批收口两件。 - [ ] 核对实现排序在案:5.1 卡(含 battle_orchestrator 触面)未合回则本批不开工 -- [ ] node_map_generator.gd::10 本地 `const NODE_TYPES` 删;:166 改 `if not LevelTable.NODE_TYPES.has(String(n["type"])):`——头注如有词表自述随改 +- [ ] node_map_generator.gd::10 本地 `const NODE_TYPES` 删;:136 改 `if not LevelTable.NODE_TYPES.has(String(n["type"])):`——头注如有词表自述随改 - [ ] 新增 tests/unit/core/encapsulation_p2_sweep_test.gd(extends SceneTree+Kit.check 主通道,全类型标注;源 token 扫描手法沿 encapsulation_sweep_test.gd〔5.1 卡新增件〕先例)断言组:①node_map_generator.gd 非空+`^const NODE_TYPES` 零命中+`LevelTable.NODE_TYPES.has(` 正锚〔架构P2 V1〕;②全仓 .gd 生产面(core/data/presentation)`NODE_TYPES :=` 定义恰好 1 处且落 data/schemas/level_table.gd〔架构P2 V2〕——两组均带扫描面非空前置 - [ ] 孤立验证:新 sweep 单件先跑绿;node_map_determinism_test 全套绿(生成链同种子逐位——R1 零行为变更主证)+关卡表加载路径(level_table 校验活检查)经既有套件覆盖零转红+冒烟零转红 - [ ] run_all.gd manifest 追加 1 行:encapsulation_p2_sweep_test(expect 0,注记「R1 结构性零命中扫描〔架构P2〕」) @@ -98,7 +98,7 @@ T1 0.25。区间合计 0.25–0.5 工作日;**精确汇总 0.25 工作日**( | 需求点 | 改动(文件:行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 | |---|---|---|---|---|---|---| -| R1 NODE_TYPES 单点化 | node_map_generator :10 删+:166 改指 | encapsulation_p2_sweep_test〔架构P2 V1/V2〕;node_map_determinism_test 既有全套(同种子同参数必产同图逐位) | 单元+集成 | `LevelRunner` 关卡推进→节点图生成真实入口;`LevelTable` 表行加载校验 | 词表定义唯一落点(正锚计数=1);生成链同种子逐位同 | 既有:节点图生成合法性与同种子复现;既有:起关/选路/断点重生成同图(集成) | +| R1 NODE_TYPES 单点化 | node_map_generator :10 删+:136 改指 | encapsulation_p2_sweep_test〔架构P2 V1/V2〕;node_map_determinism_test 既有全套(同种子同参数必产同图逐位) | 单元+集成 | `LevelRunner` 关卡推进→节点图生成真实入口;`LevelTable` 表行加载校验 | 词表定义唯一落点(正锚计数=1);生成链同种子逐位同 | 既有:节点图生成合法性与同种子复现;既有:起关/选路/断点重生成同图(集成) | **零行为改动面的证据义务**:本卡一行均为非行为改动——零变更证明=既有套件零转红+sweep 恒零+确定性链逐位。能力行全部「既有」、零新增——判断依据:零行为变更=玩家可观测能力面零变化;能力清单零编辑(批末核对义务在 T1)。 diff --git a/待办清单.md b/待办清单.md index 00fabbab..8bd765dc 100644 --- a/待办清单.md +++ b/待办清单.md @@ -16,9 +16,9 @@ **实况**:2026-10-29 全库架构静态审计的四组待裁余项,自「架构审查优化讨论」条目迁入(该条目的 3.1+3.2 部分已随迭代 50 卡③实现合回〔合并提交 8d3a12ec〕,余项不在本卡,按未决先迁再死迁立本条)。四组余项(审计待裁点 ④⑤⑥⑦,读数为审计时点,逐项现值以仓库为准):①守卫闸面缺口——S1/S2 随机函数扫描面止步 core+presentation(sim 4 处/probe 1 处/tests 3 处自建 RNG 不在扫)、S9 类型闸与 S13 质量闸扫描面不含 sim/probe/tests、S8 是 9 文件显式清单(缺位自检只防删改不防增);②S13 质量闸豁免存废——审计时点三处豁免常态化到最大户文件(battle_orchestrator 已随拆件批收窄,余量以闸件为准);③零测试点名四件(attune_loadout/battle_fx_host/meta_state_store/slot_store);④架构文档漂移三处(architecture.md 登记的 core/hero_ledger.gd 盘上不存在且测试断言它必须不存在、行数过期、EC8 热重载门后 ConfigDb.reload() 零调用方且走 load() 拿不到磁盘新值)。凭据:reports/审计-全库架构审查-2026-10-29.md(待裁点节)+reports/处置-架构审查3.1+3.2整改-2026-11-02.md(3.1+3.2 闭合凭据,随迭代 50 合回)。 -**缺口**:四组余项中①②③ 已裁完并落地(见下 2026-11-03 记录),还差④**架构文档漂移三处**的裁决与落文(`architecture.md` 的 HeroLedger 登记行、battle_orchestrator 行数与成员数、EC8 热重载门后 `ConfigDb.reload()` 零调用方)——属审计 §5.2/待裁点⑦,需再走一次设计讨论;同族的审计 §5.1(settlement 私有成员直取,实测 105 处)/§5.3(NODE_TYPES 词表双份)/§5.4(MetaProgression 取依赖形态)尚未登记本条,随④同批处置时一并入册。 +**缺口**:四组余项中①②③ 已裁完并落地(见下 2026-11-03 记录);④**架构文档漂移三处**的落文档由并行 worktree 批(arch51-docs——HeroLedger 行拆件四件补登记+行数冻结计数摘除+MetaProgression 补登记行)承载,随其合回销号;同族审计 §5.1 已登记已写卡(arch51-card 批)、§5.3 已写卡(见下 2026-11-04 段,本 worktree)、§5.4(MetaProgression 登记零动作)已随 arch51-docs 落文——均随各自合回入册;presentation 层私取面约 227 行另开设计讨论,为本条最后余项。 -**2026-11-03 P2 部分(5.1 封装+5.2 文档漂移+5.3 词表)推进**:5.1 设计闭合+已写卡——处置记录落 arch51-docs worktree、需求卡片 v1.1(godot-master 终审七项折入,pipeline_gate PASS)落 arch51-card worktree,两件随各自合回落 master 后互见;5.2 文档漂移归真已落档(architecture.md v1.32——HeroLedger 行拆件四件补登记/冻结计数摘除/MetaProgression 补登记行/CurioStop 与 RunLedger 旧指称订正,arch51-docs worktree 提交 63fc3e74+e614773a,文档域闸全绿);**EC8 热重载侧经用户裁决撤卡**——GDD 规格恢复原状(本批一度摘除已撤回)、config_db 门与 reload+编排器两行开门点代码原样保留为将来实装骨架,实装去向=用户另立待办条目+后续实装卡(他会话写卡);5.3 已写卡——凭据=reports/需求卡片-架构审查P2代码面批-2026-11-03.md v1.1(archp2-card worktree,仅 NODE_TYPES 词表单点化,零待裁点,估时 0.25 工作日,排序在 5.1 卡后);**未闭合余项收窄**=闸面缺口(S1/S2/S9/S13 扫描面、S8 目录域)、S13 三处豁免存废、零测试点名四件、presentation 层私取面约 227 行(另开设计讨论)。 +**2026-11-03 P2 部分(5.1 封装+5.2 文档漂移+5.3 词表)推进**:5.1 设计闭合+已写卡——处置记录与需求卡片 v1.1(godot-master 终审七项折入,pipeline_gate PASS)落 arch51-card worktree、处置记录落 arch51-docs worktree,随各自合回落 master 后互见;5.2 文档漂移归真已落档(architecture.md——HeroLedger 行拆件四件补登记/冻结计数摘除/MetaProgression 补登记行/CurioStop 与 RunLedger 旧指称订正,arch51-docs worktree 提交 63fc3e74+e614773a,文档域闸全绿);**EC8 热重载侧经用户裁决撤卡**——GDD 规格恢复原状(本批一度摘除已撤回)、config_db 门与 reload+编排器两行开门点代码原样保留为将来实装骨架,实装去向=用户另立待办条目+后续实装卡(他会话写卡);5.3 已写卡——凭据=reports/需求卡片-架构审查P2代码面批-2026-11-03.md v1.1(archp2-card worktree,仅 NODE_TYPES 词表单点化,零待裁点,估时 0.25 工作日,排序在 5.1 卡后,行号已按迭代 50 合回后现址换代 :136);**未闭合余项收窄(2026-11-04 并 master 后对账)**=仅剩 presentation 层私取面约 227 行(另开设计讨论)——闸面缺口、S13 豁免存废、零测试点名三组已随 §4 批(2026-11-03 裁决+闸件落地,见上裁决段)闭合销号。 **改动面**:文档+游戏代码+工具代码 From 5be1ebd47ef3b426696e8583746f5a04942e4eeb Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 4 Nov 2026 00:58:58 +0800 Subject: [PATCH 12/19] =?UTF-8?q?=E5=86=99=E5=8D=A1(EffectPort=E8=93=84?= =?UTF-8?q?=E5=8A=9B=E5=B1=82=E5=88=A0=E9=94=AE=E6=89=B9):=20=E5=8D=A1v1.0?= =?UTF-8?q?=E2=80=94=E2=80=94biz=5Ffact=E4=BA=94=E9=94=AE=E6=94=B6?= =?UTF-8?q?=E7=AA=84=E5=9B=9B=E9=94=AE+=E8=93=84=E5=8A=9B=E5=B1=82?= =?UTF-8?q?=E8=B4=A6=E6=9C=AC/=E8=BD=AC=E8=93=84=E5=88=86=E6=94=AF/charge?= =?UTF-8?q?=5Ffull/=E8=AF=8D=E8=A1=A8=E4=B8=A4=E4=BD=8D+=E6=B3=A8=E9=87=8A?= =?UTF-8?q?15=E5=A4=84=E4=B8=80=E6=AC=A1=E6=B8=85=E9=80=80;=20=E7=8E=B0?= =?UTF-8?q?=E7=8A=B6=E8=80=83=E8=AF=81=E8=A1=A5=E5=85=A8(transfer=E5=BD=A2?= =?UTF-8?q?=E6=80=81=E6=97=A0=E6=89=A7=E8=A1=8C=E4=BD=93=C2=B7transfer=3Dt?= =?UTF-8?q?rue=E9=9B=B6=E6=B5=8B=E8=AF=95=C2=B7effect=5Fport=5Ftest?= =?UTF-8?q?=E6=97=A0charge=5Flayers=E7=9B=B4=E6=8E=A5=E6=96=AD=E8=A8=80?= =?UTF-8?q?=E2=86=92=E9=AA=8C=E6=94=B6=E6=94=B9V4=E5=AE=BF=E4=B8=BB?= =?UTF-8?q?=E5=BA=94=E7=AD=94null=E6=96=B0=E6=96=AD=E8=A8=80;=20treasure?= =?UTF-8?q?=5Feffects=5Ftest=E4=B8=89=E5=A4=84=E8=B0=83=E7=94=A8=E7=AD=BE?= =?UTF-8?q?=E5=90=8D=E9=80=82=E9=85=8D=E6=96=AD=E8=A8=80=E5=80=BC=E9=9B=B6?= =?UTF-8?q?=E5=8F=98=E5=B7=B2=E7=94=B3=E6=8A=A5);=20=E8=93=84=E5=8A=9B?= =?UTF-8?q?=E5=91=A8=E8=BD=AC/=E6=95=8C=E6=96=B9=E8=93=84=E5=8A=9B/RAP?= =?UTF-8?q?=E4=B8=89=E5=9F=9F=E9=9B=B6=E8=A7=A6=E7=A2=B0=E7=BA=A2=E7=BA=BF?= =?UTF-8?q?+MC=E9=9B=B6=E8=B7=91;=20=E9=9B=B6=E5=BE=85=E8=A3=81=E7=82=B9?= =?UTF-8?q?=E5=BC=80=E5=B7=A5=E9=97=A8=3Dgrilling+=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E8=A3=81=E5=86=B3+=E7=BC=96=E8=BF=AD=E4=BB=A3(=E5=8D=95?= =?UTF-8?q?=E5=8D=A1=E2=89=881.0=E5=B7=A5=E4=BD=9C=E6=97=A5=E5=BE=85?= =?UTF-8?q?=E5=87=91=E6=89=B9);=20=E5=BE=85=E5=8A=9E=E6=9D=A1=E7=9B=AE?= =?UTF-8?q?=E6=8E=A8=E8=BF=9B=E5=B7=B2=E5=86=99=E5=8D=A1;=20pipeline=5Fgat?= =?UTF-8?q?e=20PASS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...求卡片-EffectPort蓄力层删键批-2026-11-04.md | 173 ++++++++++++++++++ 待办清单.md | 6 +- 2 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md diff --git a/reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md b/reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md new file mode 100644 index 00000000..4bf73382 --- /dev/null +++ b/reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md @@ -0,0 +1,173 @@ +# 需求卡片:EffectPort 蓄力层删键批 + +> 来源:待办清单「EffectPort biz_fact 键 charge_layers——无属主数据游离出领域实体的处置」(2026-11-02 登记,来源=审计发现;需求性工程条目,证据指认在条目实况)。**唯一事实源:该条目实况所引证据链+本卡「现状事实」节代码级考证(2026-11-04 全部实查复核)。** +> 裁决沿革:删除方向 2026-11-02 用户裁(总判据「机制数据一律长在所属封装实体的内部属性(表行字段)里,全局常量与无主账本清零」);2026-11-04 本会话全仓考证确认死代码(零内容消费面)后用户发令删除。 +> 版本:v1.0(2026-11-04) + +## 1. 目标与完成定义 + +把 `charge_layers`(玩家侧蓄力层)这条从未运转的死链整链退役: + +- biz_fact 闭面五键收窄为四键(charge_layers/dig_streak/hp_ratio/rider_tier_bonus/rider_tier_crit → 后四键); +- 行动经济侧蓄力层账本、上限常量、转蓄分支、`charge_full` 事件发射全部删除;`finish_round_stop` 签名简化为纯 RAP 转存; +- 效果引擎两词表位(事件 `charge_full`、事实 `charge_layers`)退役; +- 代码注释里引用退役专长名(整备军备/铁壁整备/厚积薄发)与蓄力层的全部残留句清零。 + +**完成定义**:`game/` 下除 `swap_charge_layers` 计数器域(蓄力周转专长,在役另物)外,「蓄力层」概念零残留(grep 判据见 T1);两套件既有断言全绿+本卡新断言绿;`--code` 域全套闸绿;RAP 转存读数逐位零漂移。 + +## 2. 设计事实源 + +需求性工程条目(删死码,无设计线):设计事实源=**证据指认**——待办清单条目实况证据链(`reports/审计-全库架构审查-2026-10-29.md` §3.1 B 类第 2 行+`game/core/effect_port.gd:4`+`game/core/action_economy.gd:14/37/203`)+本卡第 3 节 2026-11-04 代码级复核(file:line 逐条实查)。 + +## 3. 现状事实(2026-11-04 代码级考证) + +死链判据——入口死、出口假想、内容零注册三面同时成立: + +1. **入口死**:账本唯一写点=「停手转蓄力」分支(`game/core/action_economy.gd:202-205`),触发条件=效果表有行注册 `grant_ap(mode:transfer)`(`game/core/settlement/grant_segment.gd:281` 经 `has_effect_on` 查询);全仓 `.tres` 零命中(feats.tres 三条 grant_ap 行 :46/:284/:719、treasure_items.tres 两条 :38/:150,全无 transfer)。transfer 形态无执行体——唯一读点就是这条存在性查询(`game/core/effect_engine.gd:203/461/467` 三处注释句为仅余痕迹)。 +2. **出口假想**:消费面「厚积薄发/整备军备/铁壁按层缩放」只存在于 `game/core/damage_controller.gd:271/338/352/433` 四处注释;三名词=2026-10-08 退役旧专长(armory_prep/iron_wall/patient_burst,`design/content-archive/道具退役素材库.md:53-55`),GDD 与专长表零行。 +3. **满层事件无订阅**:`charge_full` 发射(`action_economy.gd:205`)自注「现无订阅者」(:199);`game/core/effect_engine.gd:14` 事件词表位在册。 +4. **transfer=true 分支零测试**:全仓仅 `game/tests/unit/core/treasure_effects_test.gd:132/138/144` 三处调用 `finish_round_stop(false, …)`(RAP 转存态)。 +5. **RAP 转存=在役正路**:术语表.md:34-35(RAP 词条与停手/转存率词条)、行动经济.md:80-82(停手整节)、`game/tests/README.md:123`(「停手转存储备与轮内刷新」能力行)。 + +残留面全清单(13 处+词表注释 3 处,处置见 T 卡): + +| # | 文件:行 | 残留 | +|---|---|---| +| 1 | `game/core/action_economy.gd:14` | `CHARGE_LAYER_CAP := 3` 常量 | +| 2 | `game/core/action_economy.gd:35-43` | 蓄力流注释块+`_charge_layers` 账本+`charge_layers` getter | +| 3 | `game/core/action_economy.gd:168` | 「转蓄力层替代 RAP 转存」注释句 | +| 4 | `game/core/action_economy.gd:196-205` | `finish_round_stop` transfer 分支+`charge_full` 发射 | +| 5 | `game/core/effect_port.gd:4-5` | 闭面五键声明 | +| 6 | `game/core/effect_engine.gd:14` | EVENTS 词表 `charge_full` 位 | +| 7 | `game/core/effect_engine.gd:59` | FACTS 词表 `charge_layers` 位 | +| 8 | `game/core/effect_engine.gd:203/461/467` | transfer 订阅查询与族分类注释句三处 | +| 9 | `game/core/battle_fx_host.gd:2/37` | 头注与 facts_inject 注释句 | +| 10 | `game/core/battle_fx_host.gd:92-98/219-223` | charge_layers 应答分支两处(读 `action_economy.charge_layers`) | +| 11 | `game/core/battle_orchestrator.gd:113` | 「charge_layers 归 fx_host 自答」注释句 | +| 12 | `game/core/damage_controller.gd:271/338/352/433` | 退役专长名注释四处 | +| 13 | `game/core/settlement/grant_segment.gd:262/279-282` | 「整备转蓄力」注释+`has_effect_on(…,"transfer")` 判定入参 | +| 14 | `game/core/settlement/combat_segment.gd:35-36` | 蓄力层注释 | +| 15 | `game/tests/unit/battle_settlement/effect_port_test.gd:16/57/103` | 注释把在役蓄力周转计数器误标为「整备军备蓄力层」、把合成对照行说成「现役铁壁」 | + +## 4. 设计契约(🔴 违反即 L3 停机呈报) + +1. 🔴 **RAP 转存路径逐位零变化**——`finish_round_stop` 的 RAP 分支、`transfer_pct` 通道、`rap_transfer_mult`(储备罐 125=1.25:1)读数逐位不动;`treasure_effects_test` 既有断言期望值零变化(仅调用签名适配,见第 8 节申报)。 +2. 🔴 **蓄力周转专长域零触碰**——`feats.tres:1007-1056`(swap_charge_layers 计数器行)、`refresh_feats_test.gd` V8 全组、`game/tests/README.md:126` 能力行、GDD 战斗结算.md:278 与奇物.md:109 行,全部不动。 +3. 🔴 **敌方蓄力域零触碰**——empower 增益技(status_effects.tres)、敌方节点级蓄力层(01-核心循环.md:79/88)、音频.md 蓄力拍等 GDD 行,全部不动;术语表**不新增**任何「蓄力」词条。 +4. 🔴 **biz_fact 闭面只收窄不扩**——四键为终态,禁顺手加新键;未绑缺省与未知事实回落 null 语义不变(fail-fast 既有机制零回归)。 +5. 🔴 **禁保留无效成员**——禁兼容别名、空 getter、词表空位、恒 false 分支、注释式「以后要用」存根;机检键与本卡契约互斥时停卡呈报,禁自造第三条路。 +6. 🔴 **实现批禁写 `design/` 整个目录与根规则文件**——architecture.md 两处(:124/:146)走反哺点清单由文档批落文。 +7. 🔴 **MC/模拟零跑**——本批无数值改动(死码删除零表值触面)。 +8. 🔴 **车道铁律**——实现走独立 worktree,主区只作合并落点。 + +## 5. 范围边界 + +**做**:上表 15 处残留一次清完+两处测试适配+1 条新断言。 +**不做**: +- `test_charge_layers_consumed_same_round` 函数**不改名**——它是 swap_charge_layers(蓄力周转)测试,函数名属该计数器域;且 README:126 能力行代表用例名锚定此名,实现批禁写 README。 +- 蓄力周转、敌方蓄力、RAP/转存率任何面(契约 1–3)。 +- 蓄力周转测试面牵连核对结论:`refresh_feats_test` V8 组全部经效果引擎计数器域运行,不触 `action_economy.charge_layers`(全仓 grep 已证)——零牵连,无需同批改动。 +**明示不收件的去向**:无——单链清退一次做完,无拆尾。 + +## 6. 关联文档同步面 + +| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 | +|---|---|---| +| `design/engineering/architecture/architecture.md` | :124(BattleFxHost 行「A3 action_economy(queue_ap_delta/charge_layers 读)」依赖句);:146(轴戊 EffectPort 句「闭面五键」与「facts 取值束 dig_streak/charge_layers/rider_tier_*」) | 实现批禁写——逐条登记进 `reports/iter-反哺点-<日期>.md`,由用户裁决后归文档批改四键、删读依赖句 | +| `game/tests/README.md` | :88 能力行「效果发射端口单点」代表用例 `_test_biz_fact_face_closed` | 实现批禁写——计划函数名不变,批末收尾核对名实一致;若实现改名则回表(记反哺点) | +| 待办清单 | 本条目状态(写卡段→已写卡;实现完成→整条删除) | 状态推进由流水线各段承载,实现批不碰 | +| 术语表/GDD 各系统文档 | 零关联(敌方蓄力/蓄力周转/RAP 各行不受影响) | 无同步义务 | + +## 7. 任务卡 + +**卡前文件结构图**(本批零新增文件;改动文件 9+测试 2,全部「非行为改动/行为改动」已标): + +| 文件 | 职责与改动 | 行为改动 | +|---|---|---| +| `game/core/action_economy.gd` | 删常量/账本/getter/transfer 分支;`finish_round_stop` 签名简化;注释两处清 | 是(对照表行 2) | +| `game/core/settlement/grant_segment.gd` | 调用简化(删 has_effect_on 入参)+注释清 | 是(对照表行 2) | +| `game/core/effect_engine.gd` | EVENTS/FACTS 删位+注释三处清 | 是(对照表行 3) | +| `game/core/battle_fx_host.gd` | 应答分支两处删+头注/注释清 | 是(对照表行 1) | +| `game/core/effect_port.gd` | 闭面五键句改四键 | 否(注释) | +| `game/core/battle_orchestrator.gd` | 注释句清 | 否(注释) | +| `game/core/settlement/combat_segment.gd` | 注释清 | 否(注释) | +| `game/core/damage_controller.gd` | 退役专长名注释四处清 | 否(注释) | +| `game/tests/unit/battle_settlement/effect_port_test.gd` | 新断言+误标注释三处清 | 是(对照表行 1) | +| `game/tests/unit/core/treasure_effects_test.gd` | 三处调用签名适配(断言值零变化) | 否(适配,申报见第 8 节) | + +### T0 契约收窄原子批(≈0.625 工作日) + +> 九文件一次改完——`battle_fx_host.gd:98/223` 读 `action_economy.charge_layers`,拆卡必产生不可编译中间态,故同卡原子交付。 + +- [ ] `action_economy.gd`:删 :14 常量、:35-43 账本块(`_charge_layers`/getter/注释)、:168 句;`finish_round_stop` 改签名 `func finish_round_stop(transfer_pct: int = 100) -> void`,体只留 RAP 转存行 `_rap += _last_stop_ap * maxi(1, transfer_pct) / 100` 与 `_last_stop_ap = 0`;:196-199 注释改写为纯 RAP 转存口径(禁残留 transfer/charge_full 字样) +- [ ] `grant_segment.gd`::281-282 调用改 `oc.action_economy.finish_round_stop(rap_pct if rap_pct > 0 else 100)`;:262 注释删「整备转蓄力」句(保留 round_end 其余语义句) +- [ ] `effect_engine.gd`:EVENTS 删 `"charge_full"` 位(:14)、FACTS 删 `"charge_layers"` 位(:59);:203 句改「发射点缺省行为仲裁用——round_end 走 RAP 转存」、:461/:467 删「grant_ap(mode:transfer)」字样(族分类句同步改写) +- [ ] `battle_fx_host.gd`:删 :92-98 与 :219-223 两处 charge_layers 分支(`biz_fact`/补充事实面走既有「未知事实回落 null」末行);:2 头注「charge_layers 自答,余五事实转宿主」改「余事实转宿主」口径;:37 注释删 charge_layers 句 +- [ ] `effect_port.gd`::4-5 闭面句改四键(dig_streak/hp_ratio/rider_tier_bonus/rider_tier_crit) +- [ ] `battle_orchestrator.gd:113`:注释删「charge_layers 归 fx_host 自答」句 +- [ ] `combat_segment.gd:35-36`:注释改写(删蓄力层句,保留端口闭面语义句) +- [ ] `effect_port_test.gd`:V3 组 `_test_biz_fact_face_closed` 末尾增断言——经 `begin_battle` 真实装配链取宿主 `biz_fact("charge_layers")`,`Kit.check("V4 闭面收窄:charge_layers 键退役——宿主事实应答 null", orch.fx_host().biz_fact("charge_layers") == null)`(print 标签文案可代拍板) +- [ ] `treasure_effects_test.gd:132/138/144`:三处调用改单参 `finish_round_stop(100)`/`finish_round_stop(125)`/`finish_round_stop(125)`(断言期望值逐字不动) +- [ ] 孤立验证:`…console.exe --script res://tests/run_all.gd` 单测域全绿(重点 effect_port_test/treasure_effects_test/refresh_feats_test 三套件) + +### T1 注释清尾与零残留核验(≈0.25 工作日) + +- [ ] `damage_controller.gd:271/338/352/433`:四处退役专长名注释删或改写为现状口径(禁残留整备军备/铁壁/厚积薄发/charge_layers 字样;:433 行剩余的 shield 订阅面注释主体保留,只删按层缩放句) +- [ ] `effect_port_test.gd:16/57/103`:三处误标注释改写——:16 改「蓄力周转计数器(feats.tres swap_charge_layers 行)」、:57/:103 删「整备军备/铁壁」字样改现状描述 +- [ ] 零残留判据:`grep -rn "charge_layers\|charge_full\|CHARGE_LAYER\|蓄力层\|转蓄力\|厚积薄发\|铁壁\|整备军备" game/ --include="*.gd" --include="*.tres"` 除 `swap_charge_layers` 域(`refresh_feats_test.gd` 函数名 `test_charge_layers_consumed_same_round` 与 `feats.tres` swap 行)外零命中 +- [ ] S13 核对:`action_economy.gd` 类变量数较登记值只降不升(删 `_charge_layers` 后预期 10→9);其余触面同判据 +- [ ] 里程碑步出口:`tools/run_all_gates.sh --code` 全绿 + +### T2 产出物落位卡(≈0.125 工作日) + +- [ ] `reports/iter-实现报告-<日期>.md`:各卡状态+实现决定记录+测试削弱申报执行情况+实机目检总清单(本批无玩家可观测变化——登记「无实机目检项」并写明死码删除零提交面) +- [ ] `reports/iter-反哺点-<日期>.md`:architecture.md :124/:146 两条逐条落点 +- [ ] 待办清单条目整条删除归收尾段(实现批不碰) + +## 8. 验证闸(改动—验收对照表) + +| # | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 | +|---|---|---|---|---|---|---|---| +| 1 | 事实应答面收窄——charge_layers 键退役 | `battle_fx_host.gd:92-98/219-223` 两分支删 | `effect_port_test.gd` V3 组新增「V4 闭面收窄:charge_layers 键退役——宿主事实应答 null」 | 接口(单元) | `BattleOrchestrator.begin_battle()` 真实装配链(端口接线后取宿主 biz_fact) | 宿主事实应答 null 化=本批特有提交面(键在→返 0,键退役→null) | 既有:效果发射端口单点 | +| 2 | 蓄力层账本与转蓄分支退役、签名简化 | `action_economy.gd:14/35-43/168/196-205`+`grant_segment.gd:262/281` | `treasure_effects_test.gd` 既有断言三处全绿(停手 1:1 与储备罐 1.25:1 两态读数零变) | 单元 | 真实停手路径 `request_stop()`→`round_end`→`finish_round_stop` | RAP 转存既有读数零漂移(行为零变化回归锚) | 既有:停手转存储备与轮内刷新(上限/AP 不重置/刷新图零清图奖励) | +| 3 | 事件/事实两词表位退役 | `effect_engine.gd:14/59` 删位 | 静态判据:T1 零残留 grep 词表零位+`--code` 域全套闸绿 | 静态+单元 | —(词表为常量面) | 静态判据+评审注记:词表位删除无独立运行期提交面(加载期 fail-fast 校验为既有机制,非本批新增) | 既有:效果发射端口单点 | + +**测试方式两分法**:本批全部归调试接口验证(单元/接口断言);**无用户目检项**——死码删除零玩家可观测提交面(实现报告登记「无实机目检项」并写明缘由)。 +**测试削弱申报**:`treasure_effects_test.gd:132/138/144` 三处调用实参 `(false, 100/125/125)` → `(100/125/125)`——签名适配,断言期望值与检查语义逐字零变化;无断言删除、无阈值放宽、无扫描面缩小。 +**独立验收审计**:`reports/iter-验收审计-<日期>.md`,由未参与实现的会话或子代理执行,未过不得合并(test-conventions §8.7)。 +**回归措辞**:里程碑步(T1)出口跑一次 `--code` 域全套闸;卡内修复只做出红最小单元的最窄确认;新断言先行孤立验证再并入全套。 + +## 9. 异常分级 + +- **L1 自救**:注释改写笔误、grep 白名单笔误、print 标签文案。 +- **L2 记录继续**:注释改写措辞超出删除语义的级微调(记录进实现报告「实现决定记录」)。 +- **L3 停机呈报**:①删除时发现任何现役表行/效果规格/内容件引用 `charge_layers`/`charge_full`/transfer 订阅(与「零内容件」考证矛盾=上游考证缺陷,停卡退回写卡段);②S13 键上升;③全套闸红不可最小单元收敛;④机检键与本卡契约互斥(含 static_scan 计数文本冲突——禁改闸件豁免);⑤实测发现 `biz_fact("charge_layers")` 在四键终态下不返 null(宿主回落语义与考证不符)。 + +## 10. 代拍板白名单 + +1. 注释改写的具体措辞(保持原注释密度与风格,语义=删除后现状)。 +2. V4 断言的 print 标签文案。 +3. 删除后空行/排版微调。 +4. `treasure_effects_test` 三处实参写法跟随文件内既有风格(字面 100/125)。 + +## 11. 待裁点 + +零待裁点——删除方向 2026-11-02 用户裁、2026-11-04 死代码确认后发令。开工门=本卡经 grilling 复核+用户裁决+迭代编排(编入迭代批次,注意单卡 ≈1.0 工作日,迭代估时总量 <5 工作日=冻结待凑批)。 + +## 12. 落位与可复用性预检 + +- **复用面**:零新增件——验收断言复用 `effect_port_test.gd` V3 闭面组既有结构(同函数内追加,不新增文件/套件);删码批无「不能复用既有件」问题。 +- **唯一面**:删除不产生第二落点;grep 同名核查已证 `swap_charge_layers`(在役)与 `charge_layers`(退役)是两个标识符域,删除不触碰前者。 +- **分层与交互面**:删除面全在 core/settlement 内部与两测试件;效果端口六 Callable 束契约(bind_port 组装期注入)不变;Core 层零 UI 依赖不因删除面新增绕行;无数值表触面。 + +## 13. 禁为机检文本保留无效成员 + +🔴 适用:禁为迎合机检消息文本(含派生计数、S13 键值)保留或新增无效成员/别名/空位;机检键与本卡契约互斥时实现段一律停卡呈报,不得自造第三条路。 + +## 14. 实现规范预算 + +零新增文件——三查不适用。存量触面预期:`action_economy.gd` 类变量数只降不升(删 `_charge_layers`,预期 10→9);`battle_fx_host.gd` 分支删除成员数不变;其余触面仅注释行。全部触面 S13 键较登记值只降不升(T1 核对步骤承载)。 + +## 15. 拆分边界纪律 + +本卡为删除类(非拆分/收敛类),无拆出单元。红线:禁为凑指标或摊薄审查把同链残留拆多批留尾——15 处残留同链一次清完(T0/T1 的切分是审查门粒度,非范围拆分;T0 九文件原子性由编译依赖承载,见 T0 卡头注)。 diff --git a/待办清单.md b/待办清单.md index 4f781288..bb9a5a0a 100644 --- a/待办清单.md +++ b/待办清单.md @@ -311,11 +311,13 @@ #### EffectPort biz_fact 键 charge_layers——无属主数据游离出领域实体的处置(2026-11-02 登记,来源=审计发现) -**实况**:证据=reports/审计-全库架构审查-2026-10-29.md §3.1 B 类第 2 行(`CHARGE_LAYER_CAP` 自标「机制结构常量」)+`game/core/effect_port.gd:4`(biz_fact 闭面五键声明)+`game/core/action_economy.gd:14/37/203`(常量、`_charge_layers` 裸账本、transfer 分支唯一写点)。2026-11-02 架构审查讨论逐键核闭面:其余四键各有领域实体持有数据(hp_ratio=主角生命、dig_streak=战斗轮次事实、rider_tier 两键=每战复位的战斗事实束),唯 charge_layers 背后是 action_economy 裸账本——全仓零内容件注册「停手转蓄力」订阅(.tres 零命中),damage_controller 三处「厚积薄发/铁壁按层缩放」仅存于代码注释描述的假想订阅面,无任何表行或效果规格实际消费。用户裁决=删除方向,总判据「机制数据一律长在所属封装实体的内部属性(表行字段)里,全局常量与无主账本清零」。处置范围:①闭面五键收窄为四键(charge_layers 键退役、effect_port_test 对应断言同改——触及迭代 49 卡①刚立的端口契约,卡内申报契约改动);②`_charge_layers` 账本、`finish_round_stop` transfer 分支、`charge_full` 事件位、`CHARGE_LAYER_CAP` 常量随键退役;③蓄力周转专长(feats.tres swap_charge_layers 计数器,文档口径「成功刷新攒层」与实现一致)不受影响,写卡时核对其测试面无牵连。 +**实况**:证据=reports/审计-全库架构审查-2026-10-29.md §3.1 B 类第 2 行(`CHARGE_LAYER_CAP` 自标「机制结构常量」)+`game/core/effect_port.gd:4`(biz_fact 闭面五键声明)+`game/core/action_economy.gd:14/37/203`(常量、`_charge_layers` 裸账本、transfer 分支唯一写点)。 + +需求卡片 reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md(2026-11-04,v1.0——写卡段代码级复核补全残留面 15 处与词表注释 3 处、transfer 形态无执行体考证、transfer=true 零测试考证;新增考证修正=effect_port_test 实测无 charge_layers 直接断言,V3 闭面组用 hp_ratio/battle_index 两对照行,故验收断言改为 V4「宿主 biz_fact 应答 null」新断言)。2026-11-02 架构审查讨论逐键核闭面:其余四键各有领域实体持有数据(hp_ratio=主角生命、dig_streak=战斗轮次事实、rider_tier 两键=每战复位的战斗事实束),唯 charge_layers 背后是 action_economy 裸账本——全仓零内容件注册「停手转蓄力」订阅(.tres 零命中),damage_controller 三处「厚积薄发/铁壁按层缩放」仅存于代码注释描述的假想订阅面,无任何表行或效果规格实际消费。用户裁决=删除方向,总判据「机制数据一律长在所属封装实体的内部属性(表行字段)里,全局常量与无主账本清零」。处置范围:①闭面五键收窄为四键(charge_layers 键退役、effect_port_test 对应断言同改——触及迭代 49 卡①刚立的端口契约,卡内申报契约改动);②`_charge_layers` 账本、`finish_round_stop` transfer 分支、`charge_full` 事件位、`CHARGE_LAYER_CAP` 常量随键退役;③蓄力周转专长(feats.tres swap_charge_layers 计数器,文档口径「成功刷新攒层」与实现一致)不受影响,写卡时核对其测试面无牵连。 **改动面**:游戏代码 -**状态**:待写卡 +**状态**:已写卡 #### 主角棋盘小人像素管线重产——原「美术资产链路审计两项 P0」之 P0②(2026-10-09 登记,来源=审计发现) From 4d141c9730346423a9f412fb878e0296c69341f0 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 4 Nov 2026 01:14:21 +0800 Subject: [PATCH 13/19] =?UTF-8?q?=E6=96=87=E6=A1=A3(=E6=A3=8B=E7=9B=98?= =?UTF-8?q?=E5=B0=8F=E4=BA=BA=E9=87=8D=E4=BA=A7=E6=9D=A1=E7=9B=AE=E6=B3=A8?= =?UTF-8?q?=E9=94=80=C2=B7=E7=94=A8=E6=88=B7=E8=A3=81):=20=E5=BE=85?= =?UTF-8?q?=E5=8A=9E=E6=B8=85=E5=8D=95=E3=80=8C=E4=B8=BB=E8=A7=92=E6=A3=8B?= =?UTF-8?q?=E7=9B=98=E5=B0=8F=E4=BA=BA=E5=83=8F=E7=B4=A0=E7=AE=A1=E7=BA=BF?= =?UTF-8?q?=E9=87=8D=E4=BA=A7=E3=80=8D=E6=95=B4=E6=9D=A1=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E2=80=94=E2=80=94=E7=94=A8=E6=88=B7=202026-11-04=20=E8=A3=81?= =?UTF-8?q?=E7=8E=B0=E4=BB=B6=E5=8D=B3=20Alpha=20=E7=BB=88=E7=A8=BF?= =?UTF-8?q?=E3=80=81=E4=B8=8D=E5=81=9A=E9=87=8D=E4=BA=A7;=E5=AE=9E?= =?UTF-8?q?=E6=B5=8B=E5=87=AD=E6=8D=AE=3Dcharacter=5Fhero=5Fidle/walk=20?= =?UTF-8?q?=E4=B8=A4=E4=BB=B6=2032=C3=9732=20=E5=94=AF=E4=B8=80RGB=20256/2?= =?UTF-8?q?53=E8=89=B2=EF=BC=8B=E5=8D=8A=E9=80=8F=E6=98=8E=E5=83=8F?= =?UTF-8?q?=E7=B4=A0293/289(=E6=8F=92=E5=80=BC=E5=BD=A2=E6=80=81=E5=9C=A8?= =?UTF-8?q?=E6=A1=88,=E4=B8=8E2026-10-06=E5=AE=A1=E8=AE=A1=E5=88=A4?= =?UTF-8?q?=E5=AE=9A=E7=9B=B8=E7=AC=A6),=E5=90=8C=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E7=AB=99=E6=A1=A9=E7=AB=8B=E7=BB=9832=E8=89=B20=E5=8D=8A?= =?UTF-8?q?=E9=80=8F=E6=98=8E=E4=B8=BA=E5=AF=B9=E7=85=A7;=E8=AF=A5?= =?UTF-8?q?=E4=B8=A4=E4=BB=B6=E4=B8=8D=E5=9C=A8=20standee=5Fasset=5Fcheck?= =?UTF-8?q?=20=E8=89=B2=E6=95=B0=E9=97=B8=E6=B8=85=E5=8D=95(=E5=8F=AA?= =?UTF-8?q?=E8=A6=86=E7=9B=96=E7=AB=99=E6=A1=A911=E4=BB=B6),=E6=95=85?= =?UTF-8?q?=E6=97=A0=E9=97=B8=E4=B8=8E=E6=96=87=E6=A1=A3=E4=BE=9D=E8=B5=96?= =?UTF-8?q?;=E6=B2=BF=E9=9D=A9=E5=8F=AA=E8=BF=9B=E6=9C=AC=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E3=80=82pipeline=5Fgate=20PASS=EF=BC=8B--docs=20?= =?UTF-8?q?=E9=9B=B6=E6=96=B0=E5=A2=9E=E7=BA=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 待办清单.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/待办清单.md b/待办清单.md index bb9a5a0a..c99824ae 100644 --- a/待办清单.md +++ b/待办清单.md @@ -318,13 +318,3 @@ **改动面**:游戏代码 **状态**:已写卡 - -#### 主角棋盘小人像素管线重产——原「美术资产链路审计两项 P0」之 P0②(2026-10-09 登记,来源=审计发现) - -**实况**:主角棋盘小人未走像素管线(插值糊图),重产事项未在任何登记处在册;审计报告 HTML 件从未进版本库、现已删除,现状以本条正文为准。2026-10-13 用户令随「UI 美化三层诊断」登记:本条属第三层「观感提升」,Alpha 阶段需完成。原 P0①(文档面:两处引用已丢失的冻结样张路径)2026-10-28 按用户裁乙销号——art-bible §1.4 冻结记录与 art-status-checklist P0 样张行删路径、留「产物原件已丢失」,机检报告凭据(git 提交 7a847c7)保留。 - -**缺口**:还差美术面的重产(按像素管线重画主角棋盘小人),归美术设计段。 - -**改动面**:美术素材 - -**状态**:待美术设计 From 41aa8d8b489933e924d4b45728c14a1a96911ff5 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 4 Nov 2026 01:21:16 +0800 Subject: [PATCH 14/19] =?UTF-8?q?=E6=96=87=E6=A1=A3(=E7=AB=99=E6=A1=A9?= =?UTF-8?q?=E5=B8=A7=E5=8A=A8=E7=94=BB=E6=94=B9=E6=8E=92Beta=C2=B7?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=A3=81):=20=E5=BE=85=E5=8A=9E=E6=B8=85?= =?UTF-8?q?=E5=8D=95=E6=9D=A1=E7=9B=AE=E6=9C=AB=E5=8F=A5=E6=8D=A2=E4=BB=A3?= =?UTF-8?q?=E2=80=94=E2=80=942026-11-04=20=E7=94=A8=E6=88=B7=E8=A3=81?= =?UTF-8?q?=E7=A7=BB=E5=87=BA=20Alpha=20=E5=AE=9A=E7=89=88=E5=89=8D?= =?UTF-8?q?=E7=BD=AE=E6=B8=85=E5=8D=95,=E7=BC=BA=E5=8F=A3=E6=94=B9=20Beta?= =?UTF-8?q?=20=E7=AB=8B=E9=A1=B9=E6=89=B9=E6=8B=8D=E6=9D=BF,=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=94=B9=E5=BE=85=E7=BE=8E=E6=9C=AF=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?(=E5=A4=87=E9=80=89);=E6=A0=87=E9=A2=98=E3=80=8CAlpha=20?= =?UTF-8?q?=E5=AE=9A=E7=89=88=E9=97=B8=E5=89=8D=E5=AE=8C=E6=88=90=E3=80=8D?= =?UTF-8?q?=E6=8C=89=E7=99=BB=E8=AE=B0=E5=85=83=E6=95=B0=E6=8D=AE=E7=A6=81?= =?UTF-8?q?=E6=94=B9=E6=9D=A1=E6=AC=BE=E4=BF=9D=E7=95=99=E5=B9=B6=E5=9C=A8?= =?UTF-8?q?=E5=AE=9E=E5=86=B5=E6=B3=A8=E6=98=8E;08-Alpha=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E6=A0=87=E5=87=86=20v1.25=E2=86=92v1.26=E2=80=94=E2=80=94?= =?UTF-8?q?=E4=BA=94=C2=B7=E8=A1=A8=E7=8E=B0=E7=AB=99=E6=A1=A9=E5=B8=A7?= =?UTF-8?q?=E5=8A=A8=E7=94=BB=E8=A1=8C=E5=88=A0=E9=99=A4=EF=BC=8B=E5=85=AD?= =?UTF-8?q?=C2=B7Alpha=20=E4=B8=8D=E5=90=AB=E6=96=B0=E8=A1=8C(=E6=8E=92=20?= =?UTF-8?q?Beta,=E5=8F=96=E4=BB=A3=202026-10-06/10-13=20=E5=8F=A3=E5=BE=84?= =?UTF-8?q?),=E6=88=98=E6=96=97=E4=B8=80=E5=B1=8F=E6=A0=B7=E5=BC=A0?= =?UTF-8?q?=E8=A1=8C=E6=9C=AB=E5=8F=A5=E9=9A=8F=E5=8A=A8(=E8=AF=A5?= =?UTF-8?q?=E8=A1=8C=E7=9A=84=E5=AE=9A=E7=89=88=E5=89=8D=E7=BD=AE=E6=8C=87?= =?UTF-8?q?=E7=A7=B0=E6=91=98=E9=99=A4,=E4=B8=BB=E8=A7=92=EF=BC=8B?= =?UTF-8?q?=E4=B8=89Boss=20=E9=87=8D=E4=BA=A7=E4=BE=9D=E8=B5=96=E7=85=A7?= =?UTF-8?q?=E6=97=A7);02-=E7=B3=BB=E7=BB=9F=E6=B8=85=E5=8D=95=2008=20?= =?UTF-8?q?=E8=A1=8C=E7=89=88=E6=9C=AC=E6=8C=87=E9=92=88=20v1.21=E2=86=92v?= =?UTF-8?q?1.26=20=E9=A1=BA=E5=B8=A6=E8=BF=BD=E5=B9=B3=E8=90=BD=E5=90=8E?= =?UTF-8?q?=E8=B4=A6;pipeline=5Fgate=20PASS=EF=BC=8B--docs=20=E9=9B=B6?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BA=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/gdd/02-系统清单.md | 2 +- design/gdd/08-Alpha版本标准.md | 6 +++--- 待办清单.md | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/design/gdd/02-系统清单.md b/design/gdd/02-系统清单.md index 1eda5c34..9b2fb5d0 100644 --- a/design/gdd/02-系统清单.md +++ b/design/gdd/02-系统清单.md @@ -15,7 +15,7 @@ | `术语表.md` | 全库专用术语的唯一对照表——危险格/安全格/同调位/RAP/GP/真视等定义+退役词对照(2026-10-11 建立,v1.23) | | `待办清单.md`(仓库根,不属本树) | 全项目待办事项的唯一登记处;各系统文档的「待办」节只留指路存根 | | `体验验证清单.md`(仓库根,不属本树) | 需要真人试玩观测的验证项登记处(与待办清单分工:待办清单是"要拍板的事",本篇是"要玩过才知道的事");每条注明结论回流路径 | -| `08-Alpha版本标准.md` | Alpha 版本包含哪些东西的清单——里程碑 M3 的完成标准;只列条目不写内容,定义一律指路各权威文档(**已定稿 v1.21**,2026-10-13) | +| `08-Alpha版本标准.md` | Alpha 版本包含哪些东西的清单——里程碑 M3 的完成标准;只列条目不写内容,定义一律指路各权威文档(**已定稿 v1.26**,2026-10-13) | ## systems/ 五个循环 diff --git a/design/gdd/08-Alpha版本标准.md b/design/gdd/08-Alpha版本标准.md index 52ea0a53..6fb4a4fe 100644 --- a/design/gdd/08-Alpha版本标准.md +++ b/design/gdd/08-Alpha版本标准.md @@ -2,7 +2,7 @@ > **一句话定位**:本文定义这个项目的 **Alpha 版本包含哪些东西**——它是里程碑 M3 的完成标准,也是判断"还差什么"的对照表。 > **本文只列条目,不写内容**:每样东西是什么、规则怎么走,一律归各自的权威文档,本文只给指路链接。想知道某样东西的定义,请点链接,不要在本文里找解释。 -> **状态**:**已定稿(v1.25)**——2026-10-13 用户令定稿,历次升版明细见 git 提交史。Alpha 的内容范围自此冻结:增删条目一律须经用户裁决。 +> **状态**:**已定稿(v1.26)**——2026-10-13 用户令定稿,历次升版明细见 git 提交史。Alpha 的内容范围自此冻结:增删条目一律须经用户裁决。 > **成文**:2026-10-13。 ## 本文怎么用 @@ -154,10 +154,9 @@ Alpha 内以玩法循环本身的内容与表现为主(棋盘、关卡、战 | 战斗演出链(弹道 / 受击 / 血条 / 灰化) | [战斗表现](systems/战斗循环/战斗表现.md) | 在役 | | 逐行结算排播 | [settlement-summary](ux/settlement-summary.md) | 在役 | | 减动效开关 | [设置与本地化](systems/表现与支撑/设置与本地化.md) | 在役 | -| 站桩帧动画 | [待办清单](../../待办清单.md) | 待做(列入 Alpha 定版前置清单:定版前完成最小版,路线预选拆件驱动;未完成则顺延 Beta;不占功能迭代) | | 全局纹理过滤设为邻近采样 | [待办清单](../../待办清单.md) | 在役(迭代 26 · 2026-10-14 入库:default_texture_filter=0+平滑渐变件三处显式 LINEAR 白名单,翻转面全枚举闭合) | | UI 字体(全局像素字,Fusion Pixel 单套单字重) | [美术圣经](../art/art-bible.md) §7.4 | 在役(2026-10-24 用户裁现状即终稿——拉丁沿用自带字形不另接专件、不上第二字重;信息层级手段=字号档差+墨色深浅) | -| 战斗一屏样张(界面美术的终稿闸) | [美术圣经](../art/art-bible.md) §1.4 | 部分在役(规格半已闭合=目标规格清单已落 art-bible 五张规格表〔2026-10-30 合回〕,五项实装定值与样张机检随迭代 43 入库;未结半=出口未达——方向稿用户目检(体验验证清单㊶)先行,样张整体过闸随其后。站桩帧动画的定版前置与主角+三 Boss 重产依赖照旧) | +| 战斗一屏样张(界面美术的终稿闸) | [美术圣经](../art/art-bible.md) §1.4 | 部分在役(规格半已闭合=目标规格清单已落 art-bible 五张规格表〔2026-10-30 合回〕,五项实装定值与样张机检随迭代 43 入库;未结半=出口未达——方向稿用户目检(体验验证清单㊶)先行,样张整体过闸随其后。主角+三 Boss 重产依赖照旧;站桩帧动画已改排 Beta,见「六 · Alpha 不含」) | | UI 氛围层与九宫格切片观感修 | [待办清单](../../待办清单.md) | 部分在役(光柱硬边已修=连续 alpha 渐变;未结半=九宫格切片错位——Alpha 内做最小修复:核对素材尺寸,必要时重出九宫格素材,全套素材重出排 Beta;出口=结算屏与图例屏错位消失,渲染闸+用户目检通过) | | UI 元素细节修(滑轨填充 / 图标垫块 / 留白 / 开发件外泄) | [待办清单](../../待办清单.md) | 在役(迭代 26 · 2026-10-14 入库:①滑轨填充随迭代 25 注销;余②图标垫块明度差降档/③商店+营地布局修/④诊断钮迁调试浮窗 全落地) | @@ -197,6 +196,7 @@ Alpha 内以玩法循环本身的内容与表现为主(棋盘、关卡、战 | 第四关 | 排 Beta;全库无设计承载,N>3 走扩展批流程([03-内容规模](03-内容规模.md)) | | 生涯期二(历史冒险回看)与期三(图鉴) | 排 Beta;Alpha 只保留期一([生涯](systems/跨局循环/生涯.md)) | | 素材升档重产 | 排 Beta;原始动机已由八敌逐键定档解决,剩余提灯候选随 Beta 资产批重议([待办清单](../../待办清单.md)) | +| 站桩帧动画 | 排 Beta(用户 2026-11-04 裁,取代 2026-10-06 登记与 2026-10-13 补裁的「Alpha 定版前置」口径);三路线与「立绘→派生形态」管线前置依赖见 [待办清单](../../待办清单.md)「站桩帧动画」条 | | 元进度件贴图终稿 | 排 Beta;元进度图标在 Alpha 保留占位,不碍在役判定([美术资产清单](../art/art-assets-checklist.md))——营地场景图已随营地交互重做列入 Alpha(见「三 · 界面」表) | --- diff --git a/待办清单.md b/待办清单.md index c99824ae..51fdf169 100644 --- a/待办清单.md +++ b/待办清单.md @@ -197,14 +197,14 @@ #### 站桩帧动画——Alpha 定版闸前完成(2026-10-06 登记,来源=审计发现) -**实况**:审计报告 P0-3——定稿立绘零帧动画;现行动画全部程序化(死亡碎裂/受击闪白/意图徽标弹入=程序 tween,非帧资产)。用户裁定**动画是较往后的优化,Alpha 版本定版时间点之前完成即可**——当前 Alpha 开发期达成「看上去可游玩」即可。路线未拍板,审计报告三路线供重启时裁决:①**拆件驱动**(报告推荐:定稿立绘切部件〔头/躯干/臂/腿/武器〕+ 节点层级 tween 驱动——零身份漂移、帧数无限、内存小;项目已有先例=shovel_swing 三帧 + 程序化死亡碎裂)②AI 关键姿势 + 人工修 + 程序补帧 ③全 AI 逐帧(不推荐:身份漂移/像素抖动)。前置依赖=「立绘→派生形态」管线(等比整数缩放 + 降色 ≤32 + 脚底基线对齐 + 命名合规)——该管线同时是棋盘小人重出与八敌档位重算的前提。Alpha 出口裁决:列入 Alpha 定版前置清单——定版前完成最小版,路线预选拆件驱动;未完成则顺延 Beta,不占功能迭代。 +**实况**:审计报告 P0-3——定稿立绘零帧动画;现行动画全部程序化(死亡碎裂/受击闪白/意图徽标弹入=程序 tween,非帧资产)。用户裁定**动画是较往后的优化,Alpha 版本定版时间点之前完成即可**——当前 Alpha 开发期达成「看上去可游玩」即可。路线未拍板,审计报告三路线供重启时裁决:①**拆件驱动**(报告推荐:定稿立绘切部件〔头/躯干/臂/腿/武器〕+ 节点层级 tween 驱动——零身份漂移、帧数无限、内存小;项目已有先例=shovel_swing 三帧 + 程序化死亡碎裂)②AI 关键姿势 + 人工修 + 程序补帧 ③全 AI 逐帧(不推荐:身份漂移/像素抖动)。前置依赖=「立绘→派生形态」管线(等比整数缩放 + 降色 ≤32 + 脚底基线对齐 + 命名合规)——该管线同时是棋盘小人重出与八敌档位重算的前提。**2026-11-04 用户裁改排 Beta**:本条移出 Alpha 定版前置清单,Alpha 定版不再以它为闸,路线三案与上述前置管线依赖原样留到 Beta 立项再裁(取代 2026-10-06 登记与 2026-10-13 补裁的「定版前完成最小版/未完成则顺延 Beta」口径;标题「Alpha 定版闸前完成」系登记时点原文,按登记元数据禁改条款保留)。 -**缺口**:还差 Alpha 定版批的路线正式拍板(预选拆件驱动)——拍板后立帧数规格与资产工单。 +**缺口**:还差 Beta 立项批的路线正式拍板(预选拆件驱动)——拍板后立帧数规格与资产工单。 - 相关文档:[art-bible](design/art/art-bible.md) §8.4 帧数规格 · 战斗表现批 **改动面**:美术素材 -**状态**:待美术设计 +**状态**:待美术设计(备选) #### 主角描边素材侧复核(2026-10-06 登记,来源=会话提及) From ad3004a8c101d66e19d30b51d3f6ff2251a706e2 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 4 Nov 2026 01:35:29 +0800 Subject: [PATCH 15/19] =?UTF-8?q?=E6=96=87=E6=A1=A3=E8=AE=BE=E8=AE=A1(?= =?UTF-8?q?=E6=95=8C=E4=BA=BA=E7=B3=BB=E7=BB=9F=C2=B7=E6=95=8C=E7=A7=8D?= =?UTF-8?q?=E8=A1=A8=E9=80=80=E5=BD=B9=C2=B7=E7=94=A8=E6=88=B7=E4=BB=A4):?= =?UTF-8?q?=20=E6=95=8C=E7=A7=8D=E5=90=8D=E5=BD=95=E8=A1=A8=E9=80=80?= =?UTF-8?q?=E5=BD=B9=E2=80=94=E2=80=94=E8=A1=8C=E6=95=B0=E6=8D=AE=E9=80=90?= =?UTF-8?q?=E8=A1=8C=E8=AF=BBenemy.tres,=20=E5=8F=AF=E8=AF=BB=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E6=8C=87=E9=92=88=E8=B5=B0=E5=A4=96=E7=BD=AE=E5=9B=BE?= =?UTF-8?q?=E9=89=B4=E5=B7=A5=E5=85=B7;=20=E8=BE=B9=E7=95=8C=E5=8F=A5?= =?UTF-8?q?=E6=8B=86=E6=B8=85=E6=B1=A0=E6=9E=84=E6=88=90=E7=BA=AA=E5=BE=8B?= =?UTF-8?q?=E4=B8=8E=E8=A1=8C=E6=95=B0=E6=8D=AE;=20=E6=8A=A4=E7=94=B2?= =?UTF-8?q?=E6=AE=B5=E6=91=98=E6=97=A5=E6=9C=9F=E4=BF=AE=E8=AE=A2=E5=8F=99?= =?UTF-8?q?=E4=BA=8B=E7=95=99=E4=B8=A4=E8=BD=B4=E7=95=8C=E5=AE=9A;=20?= =?UTF-8?q?=E8=B0=83=E5=8F=82=E8=A1=A8=E8=A1=A5level=5Findex/row=5Fkind/de?= =?UTF-8?q?pth=5Fband=E4=B8=89=E8=A1=8C;=20=E5=AE=9A=E4=BD=8D=E8=AF=AD?= =?UTF-8?q?=E4=B9=89=E8=BF=81=E9=9A=BE=E5=BA=A6=E6=9B=B2=E7=BA=BF(?= =?UTF-8?q?=E7=AC=AC=E4=B8=80=E5=85=B3=E5=9B=BE=E7=89=88=E6=B3=A8=E8=AE=B0?= =?UTF-8?q?=E8=A1=A5=E9=A6=96=E5=8F=91=E7=94=9F=E6=80=81=E4=BD=8D);=20?= =?UTF-8?q?=E6=95=8C=E7=A7=8D=E5=90=8D=E5=BD=95=E6=89=A9=E5=AE=B9P1?= =?UTF-8?q?=E8=A1=8C=E4=B8=8Ehobgoblin=E7=BC=BA=E5=8F=A3=E4=B8=89=E4=BB=B6?= =?UTF-8?q?=E5=A5=97=E4=BF=AE=E6=8C=87;=20=E6=95=8C=E4=BA=BA=E7=B3=BB?= =?UTF-8?q?=E7=BB=9Fv1.6/=E9=9A=BE=E5=BA=A6=E6=9B=B2=E7=BA=BFv1.3;=20pipel?= =?UTF-8?q?ine=5Fgate=20PASS=EF=BC=8B=E7=BB=93=E6=9E=84=E5=AE=A1=E8=AE=A1P?= =?UTF-8?q?ASS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/gdd/systems/冒险循环/难度曲线与Boss.md | 4 ++- design/gdd/systems/战斗循环/敌人系统.md | 26 +++++++------------ 待办清单.md | 2 +- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/design/gdd/systems/冒险循环/难度曲线与Boss.md b/design/gdd/systems/冒险循环/难度曲线与Boss.md index fb1d892f..d0cebdb8 100644 --- a/design/gdd/systems/冒险循环/难度曲线与Boss.md +++ b/design/gdd/systems/冒险循环/难度曲线与Boss.md @@ -1,7 +1,7 @@ # 难度曲线与Boss > 一句话:难度曲线、期望值带与 Boss 设计 -> 状态:已定稿(自旧体系迁移);现行为 v1.2 +> 状态:已定稿(自旧体系迁移);现行为 v1.3 ## 设计目的 @@ -282,6 +282,8 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板 |---|---|---|---|---|---|---| | 关卡序号 × 节点深度 | enemy_id + display_name | hp | atk / [atk_min, atk_max] | [unit_count, unit_count_max] | {skill_id: weight} | armor_type + armor_class | +第一关图版注记:首发三敌种按"杂兵 → 主力 → 关底 Boss"生态位投放——地精 = 首发杂兵(教学位节点数量开战掷定,区间行值读表);熊地精 = 首发主力;食人魔酋长 = 首发关底 Boss(池独占增益技"硬化")。池构成纪律与独占技机制归[敌人系统](../战斗循环/敌人系统.md),行值读 `enemy.tres`(provisional)。 + 第二关图版注记(分支节点图批):L2 熊地精三行 = bugbear 复用(幽暗地域部族设定——display_name 熊地精系与第一关"熊地精"错开;池差异化改造 = 蓄力拍退役换突刺,复用共享技能行);巨蜘蛛 = 新敌种(群行倾向、首遇位固定数量不加骰——首遇教学位纪律);蛛化卓尔精灵 = Boss 专属池(独占技毒爆 + 权重轮廓,血量为 r_boss 口径 provisional 锚——定位本关最大单场消耗);护甲面:轻甲(蜘蛛)与魔法护甲(熊地精三行)同关错开克制面,Boss 重甲。L2 三行复用 bugbear、显示名熊地精系(2026-09-17 用户拍板);Boss 定名蛛化卓尔精灵(用户同日拍板)。节点编号 2 = 奖励点、3 = 恢复点(rest_heal_pct 行字段兑付)——不开战斗、无敌人/棋盘行。 第三关图版注记(第三关内容批):行集 = 与第二关同模板的九节点图(六战 + Boss + 奖励 + 恢复,节点编号 2/3 同为奖励点/恢复点——不开战斗、无敌人/棋盘行)。敌种生态:灰矮人 = duergar 新敌种(单体重甲中坚——第二关单体生态位的关间台阶);钩爪恐魔 = hook_horror 新敌种(群行,复用撕咬共享技能行);灰矮人石君王 = duergar_king Boss 专属池(独占妨害技大地脉动 earth_pulse = 乏力 sapped 首发——第二妨害词汇,池载荷口径同蛛网束缚)。两敌种首遇位(节点 0 / 节点 1)固定数量不加骰——首遇教学位纪律同第二关注记。克制面重轻错开:重甲灰矮人是重甲首次登台,轻甲钩爪恐魔保穿刺/普通分量有用武之地,Boss 重甲收束"轻甲 → 魔法护甲 → 重甲"教学梯度(第三档在 L3 补完)。Boss 血量 75 = Σ普通战生命期望 91 × r_boss≈0.82(provisional 锚,域 [0.5, 1.1]——Boss 锚在案口径,逐数闭合随调参批在调参日志留档)。棋盘 13×13 / Boss 14×14、密度 0.25 维持、地形变异第三关对落石(直伤 3 点)+ 矿尘(数字遮蔽)顺带铺行;armor_class 恒 0(正式投值仍归「敌方护甲等级正式行值」在案条目全表同批)。行值读 `enemy.tres` / `board_gen.tres` / `skills.tres` / `variation.tres`,全部 provisional-pending-growth(L3 口径见「期望值带」节)。 diff --git a/design/gdd/systems/战斗循环/敌人系统.md b/design/gdd/systems/战斗循环/敌人系统.md index e0200b83..c71fb47d 100644 --- a/design/gdd/systems/战斗循环/敌人系统.md +++ b/design/gdd/systems/战斗循环/敌人系统.md @@ -1,7 +1,7 @@ # 敌人系统 > 一句话:敌人数据、技能池出招、意图呈现 -> 状态:已定稿(自旧体系迁移);现行为 v1.5 +> 状态:已定稿(自旧体系迁移);现行为 v1.6 ## 设计目的 @@ -13,7 +13,7 @@ ## 系统范围 -边界这样划:本系统是战斗单位的"数据与语义层"——单位有哪些数值、技能池怎么构成、摇定之后状态怎么变,都归这里;什么时候结算、一笔伤害最终算多少、摇号怎么摇,归战斗结算编排;增益层数存放在哪,归增益状态;画成什么样,归 HUD 框架与战斗表现。本系统编排被动:自己从不主动做事,零随机、不碰界面、不订阅事件,一切等战斗结算来调。 +边界这样划:本系统是战斗单位的"数据与语义层"——单位有哪些数值、技能池的构成纪律(一张池怎么配才合法)、摇定之后状态怎么变,都归这里;每个敌种的池实际由哪些技能构成、各占多大权重,是行数据,逐行读敌人表(`enemy.tres`),调参所有权归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md);什么时候结算、一笔伤害最终算多少、摇号怎么摇,归战斗结算编排;增益层数存放在哪,归增益状态;画成什么样,归 HUD 框架与战斗表现。本系统编排被动:自己从不主动做事,零随机、不碰界面、不订阅事件,一切等战斗结算来调。 负责: @@ -76,22 +76,11 @@ | 基础攻击恒存在 | 基础攻击不许配 0(配置为 0 加载期拒绝)——零基线乘任何百分比增益恒为零,"胜利路径恒有"的保障从数据层杜绝死锁 | | 先手攻击不是敌方技能拍 | 每次结算战斗段主角先手攻击顺位最前的存活敌人,这是固定动作;奖励侧的道具与增益是基础攻击之外的规划面伤害,归[地图战斗资源](地图战斗资源.md) | -首发敌种三种——地精、熊地精、食人魔酋长(末者为首发关底 Boss);L2/L3 内容批扩至现行八种。名字是玩家可见专名,池权重与护甲等级行值一律读配置表,本表只存敌种语义模板: +名字是玩家可见专名。各敌种的行数据——名字、数量、生命、攻击、技能池、护甲两轴——逐行读敌人表(`enemy.tres`),本文不设敌种名录抄本;需要人读的敌种总览时,走外置图鉴工具(随工程批落地:从敌人表导出数据,渲染成独立打开即可阅读的静态总览页)。 -> **hobgoblin 缺口登记(2026-10-13 迭代 24 反哺④)**:敌人表有 `hobgoblin` 数据行(寻址键 (1, battle, 3) 的「大地精」行),**无立绘、不在本敌种表**——登记在案的已知缺口(敌种语义模板未成文故呈现面无定义可依),本批未动;补齐归敌种内容批(立绘+语义模板+敌种表行三件套)。 +> **hobgoblin 缺口登记(2026-10-13 迭代 24 反哺④)**:敌人表有 `hobgoblin` 数据行(寻址键 (1, battle, 3) 的「大地精」行),**无立绘、敌种语义模板未成文**(呈现面无定义可依)——登记在案的已知缺口,本批未动;补齐归敌种内容批(立绘+语义模板——行数据与投放语义已各有承载)。 -| 敌种 | 技能池构成(权重读表) | 护甲类型 | 护甲等级 | 定位 | -|---|---|---|---|---| -| 地精 | 普通攻击 + 突刺(低权重特殊技) | 行值读表 | 行值读表 | 首发杂兵;教学位节点数量开战掷定(区间行值读表) | -| 熊地精 | 普通攻击 + 蓄力 + 重击 | 行值读表 | 行值读表 | 首发主力 | -| 食人魔酋长 | 普通攻击 + 重击 + 硬化 + **震地怒击**(半血解锁——2026-10-05 技能池执行批) | 行值读表 | 行值读表 | 首发关底 Boss;硬化独占 | -| 巨蜘蛛 | 普通攻击 + 撕咬 + 蓄力 + **毒吐**(2026-10-13 迭代 24 N2 投放) | 行值读表 | 行值读表 | L2 首遇教学位(固定 2 只——首遇位不加骰) | -| 蛛化卓尔精灵 | 普通攻击 + 重击 + 毒爆 + 蛛网束缚 + **遏毒**(半血解锁) | 行值读表 | 行值读表 | L2 关底 Boss;毒爆/蛛网束缚独占 | -| 灰矮人 | 普通攻击 + 蓄力 + 重击 + **盾击**(2026-10-13 迭代 24 N2 投放) | 行值读表 | 行值读表 | L3 基线重甲位 | -| 钩爪恐魔 | 普通攻击 + 撕咬 + 蓄力 | 行值读表 | 行值读表 | L2/L3 群行位(蜘蛛同构池) | -| 灰矮人石君王 | 普通攻击 + 重击 + 大地脉动 + **岩崩**(半血解锁) | 行值读表 | 行值读表 | L3 关底 Boss;大地脉动独占 | - -护甲类型(轻甲 / 魔法护甲 / 重甲)与攻击类型的克制结算矩阵归[战斗结算](战斗结算.md),本系统只提供每个敌种的护甲类型数据——**护甲列自 2026-10-05 技能池执行批起改读表口径**(本表轮廓列不再记具体甲型:现行 L1 全轻甲 / L2 仅 Boss 魔法甲 / L3 重甲登台的错峰投放以 `enemy.tres` 行值为准;历史「本表写魔甲/重甲」与表失同步的欠账顺带清偿)。护甲等级是另一条数值轴(防守方字段,基础攻击掷点的折扣判定读数):敌人表与主角表各增 `armor_class` 一列(域 [0, 999]),掷点与折扣的结算归[战斗结算](战斗结算.md),行值投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)——三敌种首关与主角的护甲等级行值读配置表(第一关怪物 AC 相对较低,正式行值待怪物设定投值,登记[待办清单](../../../../待办清单.md)),两条轴的概念与字段禁止混用。举证:生成与护甲为数据面规则,无计算。 +护甲类型(轻甲 / 魔法护甲 / 重甲)与攻击类型的克制结算矩阵归[战斗结算](战斗结算.md),本系统只提供每个敌种的护甲类型数据——各敌种的甲型行值逐行读敌人表(`enemy.tres`)。护甲等级是另一条数值轴(防守方字段,基础攻击掷点的折扣判定读数):敌人表与主角表各增 `armor_class` 一列(域 [0, 999]),掷点与折扣的结算归[战斗结算](战斗结算.md),行值投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md)——主角与敌方的护甲等级行值读配置表(正式行值待怪物设定投值,登记[待办清单](../../../../待办清单.md)),两条轴的概念与字段禁止混用。举证:生成与护甲为数据面规则,无计算。 ### 技能池:每敌种一张带权技能池,每拍开轮摇号出招 @@ -252,7 +241,7 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(**技能错 | P1 | 个体化变体池(A 型好斗 / B 型守势、精英专属池) | 共识点 A 的 A2 案;登记[待办清单](../../../../待办清单.md) | | P1 | 全局特殊间隔旋钮 | 特殊技背靠背实测仍嫌时的备用闸;登记[待办清单](../../../../待办清单.md) | | P1 | 新效应词汇批(妨害技 + 必中附加分量已实装 2026-09-19——设计权威 proposal-status-vocabulary.md〔提案已吸收退役——现行事实源=敌人系统.md 词汇表/增益状态.md〕 v1.0,实装面 = L2 Boss 卓尔;多段命中经用户拍板退役) | 妨害类型 + rider_mult 字段已落地;登记[待办清单](../../../../待办清单.md)(已解决移除,去向见状态记录) | -| P1 | 敌种名录扩容与投放节奏(含第二关池与投放) | 投放节奏是关卡命脉,归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | +| P1 | 敌种扩容与投放节奏(含第二关池与投放) | 投放节奏是关卡命脉,归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | | P1 | 单体寻址("只打某一个敌人"的目标指定) | 归集语义与呈现已裁定(2026-10-26;语义归[增益状态](增益状态.md)〈单体寻址扩展位〉节);实现随首个单体效果的内容批落地 | | P2 | 敌方技能图鉴 / 学习呈现(玩家侧技能知识系统) | 池不公开口径下的进阶信息面;登记[待办清单](../../../../待办清单.md) | | P2 | ~~精英 / Boss 遭遇编码位~~(已完成——不设编码位:同层多遭遇由节点编号消解,关卡节点地图 v1.0⑥ 用户裁决) | — | @@ -265,6 +254,9 @@ Boss 专属身份 = 专属池承载:独占技能 + 权重轮廓(**技能错 | 参数 | 取值域 | 说明 | |---|---|---| +| level_index(关卡序号) | int ≥ 1 | 行集坐标第一维:第几关;每关必有战斗类、深度带 0 的一行(锚行)与至少一行 Boss 类行——加载校验强制;关间台阶的坐标轴,行值投值归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | +| row_kind | {battle, boss} | 行类:battle = 战斗节点配池(非 Boss 的战斗节点一律取此类),boss = 终点行集——Boss 战按终点配置,多终点各配一行(走哪条路决定打谁);开战按节点类型取对应类的行集 | +| depth_band | int ≥ 0 | 深度带 = 节点深度所在的区间(定义见核心规则「行集构成纪律」):配池按带不按点,难度坡随带递增;节点深度落在带与带之间时取首个 ≥ 深度的带键(偏难一侧);越顶带加载校验判为调参事故;带键投放归[难度曲线与Boss](../冒险循环/难度曲线与Boss.md) | | unit_count | [1, 3] | 遭遇数量区间下界;有上界的行开战时在区间内掷定,教学位节点同样掷骰 | | unit_count_max | [unit_count, 3],可省略 | 数量区间上界;开战时在区间内掷定本战实际数量;缺省 = 定值 | | atk_min / atk_max | [0, 999] 可选配对 | 攻击基线区间:开战掷定一次、整战持久;缺省 = 定值行 | diff --git a/待办清单.md b/待办清单.md index 51fdf169..b44d4ea2 100644 --- a/待办清单.md +++ b/待办清单.md @@ -4,7 +4,7 @@ #### hobgoblin 内容三件套补齐(2026-11-01 登记,来源=审计发现) -**实况**:敌人表 hobgoblin 行(寻址键 (1, battle, 3))数值完整在役、战斗正常运行,但内容三件套未交付——立绘、敌种语义模板、敌人系统.md 敌种表行均缺,呈现面因语义模板未成文无定义可依。登记凭据=[敌人系统](design/gdd/systems/战斗循环/敌人系统.md) v1.1「hobgoblin 缺口登记」节(2026-10-13 迭代 24 反哺④)。 +**实况**:敌人表 hobgoblin 行(寻址键 (1, battle, 3))数值完整在役、战斗正常运行,但内容件未交付——立绘缺、敌种语义模板未成文,呈现面因语义模板未成文无定义可依(原三件套中的「敌人系统.md 敌种表行」件随敌种名录表退役失效,2026-11-04:行数据逐行读 game/data/tables/enemy.tres、投放语义归难度曲线与Boss.md)。登记凭据=[敌人系统](design/gdd/systems/战斗循环/敌人系统.md) v1.1「hobgoblin 缺口登记」节(2026-10-13 迭代 24 反哺④)。 **缺口**:还差敌种语义模板的文档设计讨论闭合(呈现面定义、池构成口径),闭合后立绘走美术线。 From 7639ec5b3af44f960fdc95f31e46892c2f396c1d Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 4 Nov 2026 01:37:27 +0800 Subject: [PATCH 16/19] =?UTF-8?q?=E5=B7=A5=E7=A8=8B=E6=94=B9=E5=8A=A8(?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E6=95=B4=E6=94=B9=E9=98=B6=E6=AE=B53+4=C2=B7?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E4=BB=A4):=20=E9=AA=8C=E6=94=B6=E6=A1=A3?= =?UTF-8?q?=E4=B8=89=E6=A1=A3=E7=94=B3=E6=8A=A5=E8=90=BDtest-conventions?= =?UTF-8?q?=20=C2=A78.3(=E5=88=A4=E6=8D=AE=3D=E5=A4=B1=E8=B4=A5=E4=BB=A3?= =?UTF-8?q?=E4=BB=B7=E5=8D=95=E7=BB=B4,=E5=8D=A1=E5=A4=B4=E7=94=B3?= =?UTF-8?q?=E6=8A=A5U0=E7=A1=AE=E8=AE=A4=E6=94=B9=E5=88=A4,2026-11-05?= =?UTF-8?q?=E7=94=9F=E6=95=88,=E6=9C=AA=E7=94=B3=E6=8A=A5=E6=97=A7?= =?UTF-8?q?=E5=8D=A1=E6=8C=89=E9=AB=98=E6=A1=A3=E5=85=A8=E9=87=8F=E5=AE=A1?= =?UTF-8?q?=E8=AE=A1)+=E5=AE=A1=E8=AE=A1=E6=B7=B1=E5=BA=A6=E5=88=86?= =?UTF-8?q?=E7=BA=A7=E8=90=BD=C2=A78.7(=E9=AB=98=E6=A1=A3=3D=E7=8E=B0?= =?UTF-8?q?=E8=A1=8C=E5=9B=9B=E4=BB=B6=E4=BA=8B=E5=85=A8=E9=87=8F,?= =?UTF-8?q?=E4=B8=AD=E6=A1=A3=3D=E9=80=90=E8=A1=8C=E4=BF=9D=E7=95=99?= =?UTF-8?q?=E5=A4=8D=E8=B7=91=E7=9C=81=E7=95=A5=E4=BB=A5CI=E5=9B=9E?= =?UTF-8?q?=E6=89=A7=E4=BB=A3=E8=AF=81,=E4=BD=8E=E6=A1=A3=3D=E5=AF=B9?= =?UTF-8?q?=E7=85=A7=E8=A1=A8=E6=8A=BD=E6=9F=A5=E2=89=A51/3=E4=B8=94?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=94=B9=E5=88=A4=E8=A1=8C=E5=BF=85=E6=8A=BD?= =?UTF-8?q?,=E5=89=8A=E5=BC=B1=E6=A3=80=E6=9F=A5=E4=B8=8E=E4=BE=8B?= =?UTF-8?q?=E5=A4=96=E6=A0=B8=E5=AF=B9=E4=B8=89=E6=A1=A3=E5=85=A8=E4=BF=9D?= =?UTF-8?q?=E7=95=99,=E6=A1=A3=E4=BD=8D=E5=AD=98=E7=96=91=E6=8C=89?= =?UTF-8?q?=E9=AB=98=E6=A1=A3)+doc-conventions=20=C2=A712.1=E6=9D=A1?= =?UTF-8?q?=E7=9B=AE=E6=AD=A3=E6=96=87=E9=99=90=E9=95=BF=E5=8F=8C=E5=88=A4?= =?UTF-8?q?=E6=8D=AE(=E2=89=A412=E8=A1=8C=E4=B8=94=E2=89=A4700=E5=AD=97?= =?UTF-8?q?=E5=8E=BB=E7=A9=BA=E7=99=BD,=E8=BF=87=E7=A8=8B=E5=8F=99?= =?UTF-8?q?=E4=BA=8B=E5=BD=92git=E6=8F=90=E4=BA=A4=E4=BF=A1=E6=81=AF)+pipe?= =?UTF-8?q?line=5Fgate=E6=9C=BA=E6=A3=80=E4=B8=A4=E4=BB=B6(=E6=9D=A1?= =?UTF-8?q?=E7=9B=AE=E8=B6=85=E9=95=BF=E8=A1=8C/=E5=AD=97=E5=8F=8C?= =?UTF-8?q?=E5=88=A4=E6=8D=AE+=E5=8D=A1=E7=89=87=E9=AA=8C=E6=94=B6?= =?UTF-8?q?=E6=A1=A3=E7=94=B3=E6=8A=A5C4)+req-card/iter=E4=B8=A4=E6=8A=80?= =?UTF-8?q?=E8=83=BD=E9=9A=8F=E5=8A=A8(=E5=BF=85=E5=A4=87=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E7=AC=AC16=E8=8A=82/=E5=AE=A1=E8=AE=A1=E6=B7=B1?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E7=BA=A7=E5=8F=A3=E5=BE=84)+=E5=BE=85?= =?UTF-8?q?=E5=8A=9E=E6=B8=85=E5=8D=959=E6=9D=A1=E5=AD=98=E9=87=8F?= =?UTF-8?q?=E5=8E=8B=E7=BC=A9(=E8=BF=87=E7=A8=8B=E5=8F=99=E4=BA=8B?= =?UTF-8?q?=E5=BD=92git=E4=B8=8E=E8=BF=87=E7=A8=8B=E4=BB=B6=E6=8C=87?= =?UTF-8?q?=E9=92=88)+ci=5Fwatch=E4=B8=AD=E9=97=B4=E6=80=81=E8=AF=AF?= =?UTF-8?q?=E5=86=99=E7=BB=88=E5=B1=80=E7=BA=A2=E5=9B=9E=E6=89=A7=E7=BC=BA?= =?UTF-8?q?=E9=99=B7=E7=99=BB=E8=AE=B0(run=2037=E5=AE=9E=E8=AF=81:?= =?UTF-8?q?=E5=9B=9E=E6=89=A716:59=E8=AE=B0=E7=BA=A2,run=2017:03=E6=89=8Ds?= =?UTF-8?q?ucceeded,=E7=8E=B0=E6=9F=A5API=E5=85=A8=E7=BB=BF)+=E6=95=B4?= =?UTF-8?q?=E6=94=B9=E6=9D=A1=E7=9B=AE=E6=95=B4=E6=9D=A1=E5=88=A0=E9=99=A4?= =?UTF-8?q?(=E5=9B=9B=E6=96=B9=E5=90=91=E5=85=A8=E5=AE=8C=E6=88=90,?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=9C=89=E6=95=88=E6=80=A7=E5=BA=A6=E9=87=8F?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=A3=81=E6=9A=82=E4=B8=8D=E5=A4=84=E7=90=86?= =?UTF-8?q?)+=E7=9B=98=E7=82=B9=E6=8A=A5=E5=91=8A=E9=80=80=E5=BD=B9(?= =?UTF-8?q?=E5=90=B8=E6=94=B6=E5=8D=B3=E6=AD=BB,design=E9=9B=B6=E5=BC=95?= =?UTF-8?q?=E7=94=A8)+=E6=89=B9=E6=8A=A5=E5=91=8A;=20=E8=B4=9F=E8=AF=81?= =?UTF-8?q?=E4=B8=89=E4=BB=B6(=E5=AD=97=E6=95=B0829=E7=BA=A2/=E8=A1=8C?= =?UTF-8?q?=E6=95=B018=E7=BA=A2/=E9=AA=8C=E6=94=B6=E6=A1=A3=E7=BC=BA?= =?UTF-8?q?=E7=94=B3=E6=8A=A5=E7=BA=A2-=E7=94=B3=E6=8A=A5=E5=90=8E?= =?UTF-8?q?=E6=B6=88=E7=BA=A2);=20pipeline=5Fgate=20PASS=2028=E6=9D=A1?= =?UTF-8?q?=E7=9B=AE;=20--docs=E5=85=A8=E7=BB=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- design/engineering/doc-conventions.md | 2 + design/engineering/test-conventions.md | 16 +++- ...程改动报告-验收档与条目限长批-2026-11-04.md | 31 ++++++++ reports/盘点-验证与清单体系-2026-10-28.md | 46 ------------ tools/pipeline_gate.py | 25 ++++++- 待办清单.md | 74 ++++++------------- 6 files changed, 93 insertions(+), 101 deletions(-) create mode 100644 reports/工程改动报告-验收档与条目限长批-2026-11-04.md delete mode 100644 reports/盘点-验证与清单体系-2026-10-28.md diff --git a/design/engineering/doc-conventions.md b/design/engineering/doc-conventions.md index 85e8de2a..d9567a17 100644 --- a/design/engineering/doc-conventions.md +++ b/design/engineering/doc-conventions.md @@ -155,6 +155,8 @@ **状态**:按状态机取词。 ``` +**条目正文限长(2026-11-04 立)**:正文四属性只写现行状态与证据指针;过程叙事(逐轮裁定追记、「某日用户裁…」式沿革叙述、设计讨论过程复述)禁入正文——沿革与裁定史由 git 提交信息承载(第 10 节同源)。长度硬上限双判据:正文(四属性全部内容,不含标题与空行)≤12 行,且去空白字符合计 ≤700 字;任一超限即须压缩,由流水线闸机检。行数判据抓清单行蔓延,字数判据抓单行堆砌,两条并用缺一不可(实证:单行堆砌型超长条目一行可塞 1500 字,只限行数拦不住)。压缩方向=枚举与裁定细节迁 owner 文档或过程件(关联文档清单指过去),正文只留现行状态+证据指针+缺口。 + `改动面` 四档的划线判据(按被改对象的路径归属,与闸的分域同口径): | 档 | 覆盖范围 | diff --git a/design/engineering/test-conventions.md b/design/engineering/test-conventions.md index f9727317..34e25a54 100644 --- a/design/engineering/test-conventions.md +++ b/design/engineering/test-conventions.md @@ -97,6 +97,8 @@ - **反向**:diff 里每个行为改动至少一行;没有对应行的改动,必须写明「非行为改动」或「由第 X 行覆盖」。 - **测试侧**:新增或改写的每条断言至少挂一行;挂不上的孤儿断言删掉或补挂到需求点。 +**验收档申报(2026-11-04 立,自 2026-11-05 起对文件名日期不早于该日的需求卡片生效;旧卡不回头改)**:每张需求卡片在头部信息区(与设计事实源声明同区)申报一个验收档,三档:高/中/低。判据=失败代价单维——这条改动做错了,后果随存档或结算传播的(存档写读与迁移、RNG 流、战斗结算公式与乘区、经济入账、数值表结构校验)=高;后果玩家可见但不损持久状态的(常规玩法逻辑、门控、交互逻辑、呈现数据面)=中;后果即看即知且无状态残留的(文案、纯呈现样式、布局微调)=低。一张卡触多档按最高档申报;申报由写卡段落笔,用户批卡(U0)时确认或改判。档位只调节 §8.7 审计深度——闸机与 CI 的域划分、选闸算法、全量强制档一概不因档位变化,真实入口、判据绑定面、禁削弱等验收闭合判据全部照旧。未申报档位的卡一律按高档全量审计。机检=`tools/pipeline_gate.py` 判据 C4:卡内须含「验收档:高/中/低」申报行。 + **能力清单维护锚(2026-10-29 用户裁改版定稿)**:`game/tests/README.md`「能力清单」是**实现指导+阅读导航+义务声明**——只宣布「要验证什么」,不记「是否已验证/是否跑过」;落地账归现行验收闭合链(改动—验收对照表逐条挂断言+合回前独立验收审计),本清单不承载验证状态。表为四列:能力|系统|真实入口|代表用例(`文件:函数`)。**维护归写卡段,当场入表**:写需求卡片时,本批新增能力当场写入能力行——真实入口取自设计文档已定的入口,代表用例=卡里定死的计划测试(`文件:函数`);受影响存量行(入口/用例名变更)同批更新;能力退役删行。**实现照单落名**:测试函数名以清单为唯一依据,名实不符=卡片没写清=停卡退回。**收尾核对**:批末收尾只核对表上名字与实际落地一致(改名则回表),不刷任何批次字段;实现批禁写该文件的现行红线不变(process-conventions §3 第 11 条),核对义务归收尾提交。三层模型见 §8.9。改动—验收对照表纪律不变:新增或改写的每条断言仍须挂一行(上文「测试侧」);断言改判仍受 §8.4 真实入口口径约束。 **新增 core 件的覆盖登记义务(2026-11-03 架构审查 P1 余项裁)**:拆件或重构产出的新 core 文件不触发 process-conventions §3 第 6 条「新功能必配新测试」(那条只管新增玩法/机制),因此单由本条承接——新 core 件要么被 `game/tests/` 某套件按文件名或 `class_name` 点名,要么在承接它的能力行「代表用例」里申报「经宿主链覆盖(宿主=<件>)」;两者都无=批末收尾核对时补登。本条**不是覆盖率要求**,与 §7「覆盖率不是目标」同轨:登记的是能力义务的归属,不做文件计数——「每个 core 件必须被点名一次」的机器闸已裁否(它逼出为点名而点名的空套件,且与 §7 正面冲突)。落笔面沿用现行分工:申报行由写卡段入能力清单(实现批禁写该文件),核对归批末收尾提交。 @@ -126,7 +128,19 @@ 3. 检查测试削弱:删除断言、放宽阈值、缩小扫描面、换下层直调,逐处要卡片申报或用户批准。 4. 核对内部字段直查的受控例外:直查行是否已在对照表注明理由(该行为无公开可观测面可钉)。 -审计报告落 `reports/iter-验收审计-<日期>.md`,逐行写「通过/缺漏/例外及依据」。未通过不得合并。测试执行两入口铁规不变:审计在迭代 loop 内启动的子代理算 loop;另开会话须用户点名。 +**审计深度分级(2026-11-04 立)**:审计按卡内申报的验收档(§8.3)逐卡定深度;梯度只落在昂贵的判断件上,机械且堵造假向量的两件(削弱检查、例外核对)三档全保留不抽。中/低档省略的测试复跑以 CI 回执为执行证据(回执是机器产物——「不采信实现者自述已全绿」的口径不变): + +| 审计动作 | 高 | 中 | 低 | +|---|---|---|---| +| 对照表逐行核对 | 全量 | 全量 | 抽查 ≥1/3 行;新增行与改判行必抽 | +| 判据绑定面核对 | 抽查(现行口径) | 抽查(现行口径) | 抽 1 行 | +| 测试削弱检查 | 逐处 | 逐处 | 逐处 | +| 直查例外核对 | 逐条 | 逐条 | 逐条 | +| 最窄测试复跑 | 抽查(现行口径) | 省略——以 CI 回执代证 | 省略——以 CI 回执代证 | + +低档的抽查面与抽中依据照写审计报告;「每批必有审计、禁零审计批」不变;档位存疑按高档执行。 + +审计报告落 `reports/iter-验收审计-<日期>.md`,逐行写「通过/缺漏/例外及依据」,逐卡标注验收档与实际执行深度。未通过不得合并。测试执行两入口铁规不变:审计在迭代 loop 内启动的子代理算 loop;另开会话须用户点名。 ### 8.8 生效与旧卡 diff --git a/reports/工程改动报告-验收档与条目限长批-2026-11-04.md b/reports/工程改动报告-验收档与条目限长批-2026-11-04.md new file mode 100644 index 00000000..e2d57296 --- /dev/null +++ b/reports/工程改动报告-验收档与条目限长批-2026-11-04.md @@ -0,0 +1,31 @@ +# 工程改动报告:验收档分级与待办条目限长批(2026-11-04) + +> 接收方:待办清单「验证与清单体系整改——四方向分阶段推进」条(阶段 3+阶段 4 收口凭据) +> 性质:工程改动+文档设计改动直改批(用户 2026-11-04 发令开工;W 层八裁点当日全裁——档名高/中/低、判据=失败代价单维、三档、强度差只落审计深度且每批必有审计、U0 确认权、行数硬上限、入 pipeline_gate 机检、存量同批压缩;How 细则由本批推导落文) + +## 1. 改动清单 + +| 面 | 改动 | +|---|---| +| `design/engineering/test-conventions.md` | §8.3 新增「验收档申报」:三档高/中/低,判据=失败代价单维,卡头申报、U0 确认或改判,2026-11-05 起对文件名日期不早于该日的卡生效,未申报旧卡按高档全量审计。§8.7 新增「审计深度分级」梯度表:高档=现行四件事全量;中档=对照表逐行保留、复跑省略以 CI 回执代证;低档=对照表抽查 ≥1/3(新增行与改判行必抽)+复跑省略;测试削弱检查与直查例外核对三档全保留;档位存疑按高档。 | +| `design/engineering/doc-conventions.md` §12.1 | 新增「条目正文限长」:正文只写现行状态+证据指针,过程叙事归 git 提交信息;≤12 行且 ≤700 字(去空白)双判据,流水线闸机检。 | +| `tools/pipeline_gate.py` | ①待办条目限长双判据机检(行/字,超限判据名「条目超长」);②卡片验收档申报机检 C4(GRADE_RULE_DATE=2026-11-05)。 | +| `.zcode/skills/req-card`(不入 git) | 必备结构新增第 16 节「验收档申报」。 | +| `.zcode/skills/iter`(不入 git) | 独立验收审计节挂深度分级口径(逐卡定档、旧卡按高档)。 | +| `待办清单.md` | 存量超限条目 9 条压缩(架构审查余项/三关色相/验证与清单体系整改/数值标定窗口/棋盘键盘/二三关观感/封印印记/生涯/EffectPort 删键)——过程叙事归 git 提交信息与既有过程件,正文留现行状态+证据指针+缺口。 | + +## 2. How 数值与判据推导 + +- **限长 12 行**=实况说明行 1+文档指针行至多 8+缺口/改动面/状态各 1;**700 字**≈8 条指针(约 320 字)+现行状态叙述余量——以现行合规条目实测校准(压缩后的整改条目约 400 字)。行数与字数并用:单判据皆可绕(多行蔓延/单行堆砌),实证=整改条目原实况为单段 1500+ 字。 +- **审计深度梯度锚定现行 §8.7 四件事**:机械且堵造假向量的两件(削弱检查、例外核对)三档全保留不抽;昂贵的判断件(逐行核对、复跑)按档放宽;中/低档复跑省略的执行证据由 CI 回执承担(CI 全量强制档不因档位变化——迭代 44 实证的跨卡漏网兜底保持原样)。 +- **档名取「高/中/低」**:P0/P1/P2 记号已被 doc-conventions §12.1 占用为待办紧急度专用(新文档禁另立别义)。 +- **生效日 2026-11-05**:沿用卡片按文件名日期生效的惯例(§8.8 同型),当日已写卡(EffectPort 批 2026-11-04)不回头改。 + +## 3. 验证 + +- `pipeline_gate.py` 全仓 PASS(压缩后零超限);负证:临时超长条目行数与字数两判据各自触发红(临时件在 /tmp,未入库)。 +- `run_all_gates.sh --docs` 全绿;合回后远端 CI 追验(文档批=文档域秒级闸)。 + +## 4. 同批发现与登记(不在本批修) + +- `tools/ci_watch.sh` 在 run 未落定时把中间态写成终局红回执:2026-11-04 run 37(commit 536dc072)实证——回执 16:59:55 写入 verdict=red,而该 run 17:03:10 才以「Job succeeded」落定,现查 Gitea API 组合状态=success;回执与真值相反,下游按「红未修不开新批」被误阻塞(本批开工时人工查 API 解封)。已登记待办清单新条目(直改类,修复方向=只认 run conclusion 落定后的终局态)。 diff --git a/reports/盘点-验证与清单体系-2026-10-28.md b/reports/盘点-验证与清单体系-2026-10-28.md deleted file mode 100644 index 2ae0e084..00000000 --- a/reports/盘点-验证与清单体系-2026-10-28.md +++ /dev/null @@ -1,46 +0,0 @@ -# 盘点:验证与清单体系(阶段 0) - -> 2026-10-28 · 服务待办清单「验证与清单体系整改——四方向分阶段推进」条 -> 性质:过程件(吸收即死)——结论吸收进待办条目与阶段 1 设计文档后删除。 - -## 1. 结论 - -1. **验证集清单零机器闸依赖**:`tools/run_all_gates.sh`、hooks、五个项目技能均不引用它;规范性锚点只有 `design/engineering/test-conventions.md` §8.3 一处。退役不需要改闸、改钩子、改技能。 -2. **测试名尾缀不是全量追溯键**:47 个有断言的文件中 19 个零尾缀(含三条 35 条以上断言的大套件)。能力清单只能按「能力→代表用例」建,不能要求逐断言尾缀。 -3. **对照表与待办清单都有机器闸**:前者的列结构、后者的条目格式均由 `tools/pipeline_gate.py` 强制;这两处瘦身要动闸,属阶段 3/4,不是阶段 1 的顺手活。 -4. **能力清单已有现成形态**:`game/tests/README.md` 的「集成旅程清单」5 行,扩面成本低;`repo_structure_audit.py` 不限制 `game/tests/` 下的 .md 文件名。 - -## 2. 依赖面盘点 - -| 件 | 消费方 | 机器闸依赖 | 退役/改动成本 | -|---|---|---|---| -| `game/tests/验证集清单.md` | test-conventions §8.3、待办清单 1 条、2 份过程报告、`tools/extract_checks.py` | 无 | 低:改 1 条规约+删文件 | -| `tools/extract_checks.py` | 无自动调用;手工生成/对账 | 无 | 可保留为审计工具,或随清单退役 | -| 改动—验收对照表 | req-card 技能、iter 技能、`pipeline_gate.check_ledger`(强制 5 列) | 有 | 中:规约+两技能+闸三处 | -| 待办清单 | `pipeline_gate`(格式全套)、`doc_ref_audit`、`doc_term_audit`、`repo_structure_audit`、各技能 | 有 | 低:正文压缩不触机检;新增「≤5 行」规则才动闸 | -| 独立验收审计 | iter 技能、req-card 技能、`pipeline_gate`(只查「验收审计」字样) | 有(字样) | 中:改抽样规则要动两技能+规约 | -| 集成旅程清单 | 无机器消费 | 无 | 低:直接扩面 | - -## 3. 覆盖数据 - -- `game/tests/**/*.gd` 共 70 个文件;静态 `check(` 粗口径 1607 处(含 `test_kit` 定义行与 `smoke_boot` 等提取器口径外宿主),清单口径 1587 处。 -- 标签尾缀〔…〕756 个(上限口径,一条标签一个)。 -- 有断言的文件 47 个:28 个有尾缀,19 个零尾缀。 -- 零尾缀大套件:`seal_polarity` 69、`variant_placement` 42、`roll_multiplier` 35、`cross_system_flow` 22、`damage_math` 21、`skill_unlock` 20、`type_glow` 20、`minesweeper_rules` 16、`system_contracts` 15。 -- 静默收集通道 `check_quiet` 约 407 站点在提取口径外(既有备案,test-conventions §5 工具局限)。 - -## 4. 对四阶段的影响 - -| 阶段 | 盘点结论对它的约束 | -|---|---| -| 1 换尺子(A) | 先扩「集成旅程清单」到核心域;每行=能力|真实入口|代表用例|最后验证批次|缺口。退役验证集清单;`extract_checks.py` 去留在设计讨论裁 | -| 2 按新尺子精简(B) | 删并对象改为能力项;每项能力保留至少一个代表用例;不要求逐断言尾缀 | -| 3 调验收强度(C) | 对照表列与审计抽样一起改,触 `pipeline_gate`、req-card、iter 三处;不要与阶段 1 同批 | -| 4 文档减肥(D) | 待办正文压缩可直接做;「≤5 行」入闸需改 `pipeline_gate` | - -## 5. 未决点(阶段 1 设计讨论) - -1. 能力清单落点:`game/tests/README.md` 扩面,还是独立文件? -2. 能力项粒度与覆盖面:按哪些域切、预计多少行? -3. `tools/extract_checks.py` 去留:随清单退役,还是保留为审计工具? -4. 验证集清单退役时点:立即冻结,还是阶段 1 设计定稿后一并退役? diff --git a/tools/pipeline_gate.py b/tools/pipeline_gate.py index 8802bb7b..0250a681 100644 --- a/tools/pipeline_gate.py +++ b/tools/pipeline_gate.py @@ -3,7 +3,9 @@ r"""pipeline_gate.py — 工作流程流水线闸(待办清单条目状态机+roadmap 迭代总表+需求卡片口径+一次交叉核)。 职责:机检待办清单条目(标题元数据与可选优先级档名/四属性齐备与旧属性名防回潮/状态词白名单/ - 改动面四档白名单/条件凭据/无设计线段条目的证据指认/状态段累积制/特批/零命中)与 roadmap 迭代总表(六列/状态五形态/卡片与报告存在性/编入时间与预计周期的 + 改动面四档白名单/条件凭据/无设计线段条目的证据指认/状态段累积制/特批/正文限长双判据/零命中) + 与 roadmap 迭代总表(六列/状态五形态/卡片与报告存在性/编入时间与预计周期的 + 分档放行)/需求卡片口径(C1 文档义务/C2 设计事实源/C3 改动—验收对照表/C4 验收档申报)+一次交叉核。 约束:每红项一行「文件:行号 判据名 一句白话说明」,exit 0=全绿 / 1=有红 / 2=输入件缺失; 卡片与报告存在性相对 --repo-root 解析(缺省=本文件上两级);待办清单与 roadmap 均已为新格式 (2026-10-18 数据整改批),本闸已注册进 tools/run_all_gates.sh 文档域(08c 流水线闸)。 @@ -58,6 +60,12 @@ AUDIT_MARK = "验收审计" CAP_ROW_RULE_DATE = (2026, 10, 29) # req-card §8:每行标能力归属(对齐 test-conventions §8.9 三层模型) CAP_ROW_RE = re.compile(r"^(既有|新增)\s*[::]\s*(.+)$") CAP_README = Path("game/tests/README.md") +# C4 验收档申报(2026-11-04 验收强度分级批,生效 2026-11-05;test-conventions §8.3) +GRADE_RULE_DATE = (2026, 11, 5) +GRADE_RE = re.compile(r"验收档\s*[::]\s*[高中低]") +# 待办条目正文限长双判据(2026-11-04 立,doc-conventions §12.1:行数抓清单蔓延、字数抓单行堆砌) +ENTRY_MAX_LINES = 12 +ENTRY_MAX_CHARS = 700 DATE_RE = re.compile(r"\d{4}-\d{2}-\d{2}") VER_RE = re.compile(r"[vV]\d+(?:\.\d+)*") @@ -216,6 +224,17 @@ def check_todo(text, issues, where, root): for e in entries: line = e["line"] check_title(e["title"], line, issues, where) + # 条目正文限长(doc-conventions §12.1 限长规则):行数与字数双判据,不含标题与空行 + body_stripped = [raw for _, raw in e["body"] if raw.strip()] + if len(body_stripped) > ENTRY_MAX_LINES: + issues.append((where, line, "条目超长", + "正文 %d 行超上限 %d(doc-conventions §12.1:过程叙事归 git 提交信息," + "正文只留现行状态+证据指针)" % (len(body_stripped), ENTRY_MAX_LINES))) + body_chars = sum(len(re.sub(r"\s", "", raw)) for raw in body_stripped) + if body_chars > ENTRY_MAX_CHARS: + issues.append((where, line, "条目超长", + "正文约 %d 字超上限 %d(去空白计,doc-conventions §12.1 限长)" + % (body_chars, ENTRY_MAX_CHARS))) attrs, attr_line = {}, {} for ln, raw in e["body"]: s = raw.strip() @@ -635,6 +654,10 @@ def check_cards(root, issues): issues.append((str(path), 1, "独立验收审计未声明", "须在卡内写明独立验收审计入口与报告文件(2026-10-21 起," "test-conventions §9.7)")) + if when >= GRADE_RULE_DATE and not GRADE_RE.search(text): + issues.append((str(path), 1, "验收档未申报", + "须在卡片头部信息区申报「验收档:高/中/低」(2026-11-05 起," + "test-conventions §8.3)")) if when < SYNC_RULE_DATE: continue in_sec = False diff --git a/待办清单.md b/待办清单.md index bb9a5a0a..5db63a4f 100644 --- a/待办清单.md +++ b/待办清单.md @@ -14,50 +14,25 @@ #### 架构审查余项——闸面缺口、豁免存废、零测试点名与架构文档漂移(2026-11-03 登记,来源=批次移交) -**实况**:2026-10-29 全库架构静态审计的四组待裁余项,自「架构审查优化讨论」条目迁入(该条目的 3.1+3.2 部分已随迭代 50 卡③实现合回〔合并提交 8d3a12ec〕,余项不在本卡,按未决先迁再死迁立本条)。四组余项(审计待裁点 ④⑤⑥⑦,读数为审计时点,逐项现值以仓库为准):①守卫闸面缺口——S1/S2 随机函数扫描面止步 core+presentation(sim 4 处/probe 1 处/tests 3 处自建 RNG 不在扫)、S9 类型闸与 S13 质量闸扫描面不含 sim/probe/tests、S8 是 9 文件显式清单(缺位自检只防删改不防增);②S13 质量闸豁免存废——审计时点三处豁免常态化到最大户文件(battle_orchestrator 已随拆件批收窄,余量以闸件为准);③零测试点名四件(attune_loadout/battle_fx_host/meta_state_store/slot_store);④架构文档漂移三处(architecture.md 登记的 core/hero_ledger.gd 盘上不存在且测试断言它必须不存在、行数过期、EC8 热重载门后 ConfigDb.reload() 零调用方且走 load() 拿不到磁盘新值)。凭据:reports/审计-全库架构审查-2026-10-29.md(待裁点节)+reports/处置-架构审查3.1+3.2整改-2026-11-02.md(3.1+3.2 闭合凭据,随迭代 50 合回)。 +**实况**:2026-10-29 全库架构审计(reports/审计-全库架构审查-2026-10-29.md;3.1+3.2 已随迭代 50 合回,凭据 reports/处置-架构审查3.1+3.2整改-2026-11-02.md)的待裁余项,自同名讨论条目迁入。现状(2026-11-04 对账):①闸面缺口(扫描面不扩 sim/probe/tests,适用域落 code-conventions §4 第 13 条)②S13 豁免存废(豁免已清偿,基线 5 键,commit 9eedf896)③零测试点名(定性=无按文件登记惯例,承接面落 test-conventions §8.3「新增 core 件的覆盖登记义务」)三组已随 §4 批裁决并落地(2026-11-03 用户逐项点头,CI 66407117 green);④架构文档漂移三处已随 arch51-docs 批落文档合回;§5.1 封装修复已写卡(reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md v1.1,5 张 T 卡 2.875 工作日,凭据含 reports/处置-架构审查5.1封装修复-2026-11-03.md,排序在 3.1+3.2 卡后);§5.3 已写卡(reports/需求卡片-架构审查P2代码面批-2026-11-03.md v1.1,0.25 工作日,排序在 5.1 卡后);EC8 热重载侧经用户裁撤卡(实装去向=用户另立条目)。 -**缺口**:四组余项中①②③④ 全部闭合销号(④ 架构文档漂移三处已随 arch51-docs 批落文档并合回——HeroLedger 行拆件四件补登记+行数冻结计数摘除+MetaProgression 补登记行);同族审计 §5.1 已写卡并合回(arch51-card 批,见下 2026-11-03/11-04 记录)、§5.3 已写卡(见下 2026-11-04 段,本卡合回后在册)、§5.4(MetaProgression 登记零动作)已随 arch51-docs 落文合回;presentation 层私取面约 227 行另开设计讨论,为本条最后余项。 - -**2026-11-03 设计闭合+写卡(5.1 封装修复部分,2026-11-04 并 master 后凭据换代)**:2026-11-03 会话对审计 §5.1(settlement 段类私取编排器私有成员)完成设计讨论并扩面普查,裁决五处跨对象私有访问修复方案(settlement 七段→编排器束交付/搬家五方法/adventure_runner→BreakpointStore/save_manager↔SlotStore 双向公开面/grant_segment→BattleFxHost+config_db→三表容器;presentation 层约 227 行另开设计讨论不在内)。凭据=reports/处置-架构审查5.1封装修复-2026-11-03.md(处置记录)+审计报告 §5.1+architecture.md:119/:124/:137-146。需求卡片 reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md(**v1.1**——godot-master 终审七项折入〔golden 封印步改封未揭示相邻格/三 schema 解析冒烟义务/T3 签名补注解/成员账两笔订正/harmful_adjacent 自呼随更名/现值交付口径注/SlotStore→SaveManagerCore 反向私取终审补查 21 处并入 T3〕;5 张 T 卡估时精确汇总 2.875 工作日;零行为变更批,能力清单零新增行已写明判断依据);实现排序在 3.1+3.2 卡之后——该卡已随迭代 50 合回,前置已解除(combat_segment 行号漂移按卡内 grep 锚定位预案处理)。 - -**2026-11-03 P2 部分(5.2 文档漂移+5.3 词表+EC8 撤卡,2026-11-04 并 master 后入册)**:5.2 文档漂移归真已落档并合回(architecture.md——HeroLedger 行拆件四件补登记/冻结计数摘除/MetaProgression 补登记行/CurioStop 与 RunLedger 旧指称订正,arch51-docs 提交 63fc3e74+e614773a,文档域闸全绿);**EC8 热重载侧经用户裁决撤卡**——GDD 规格恢复原状(本批一度摘除已撤回)、config_db 门与 reload+编排器两行开门点代码原样保留为将来实装骨架,实装去向=用户另立待办条目+后续实装卡(他会话写卡);5.3 已写卡——凭据=reports/需求卡片-架构审查P2代码面批-2026-11-03.md v1.1(仅 NODE_TYPES 词表单点化,零待裁点,估时 0.25 工作日,排序在 5.1 卡后,消费点行号已按迭代 50 合回后现址换代 :136)。**未闭合余项对账(2026-11-04)**=仅剩 presentation 层私取面约 227 行(另开设计讨论)——闸面缺口、S13 豁免存废、零测试点名三组已随 §4 批(2026-11-03 裁决+闸件落地,见上裁决段)闭合销号。 +**缺口**:还差 presentation 层私取面(约 227 行)的设计讨论——本条最后余项;另 §5.1/§5.3 两卡待编迭代。 **改动面**:文档+游戏代码+工具代码 **状态**:文档设计中 -**2026-11-03 设计讨论裁决(①②③ 三组,用户逐项点头)**:凭据=reports/审计-全库架构审查-2026-10-29.md §四 各节「2026-11-03」标注。①**闸面缺口**——S9 类型闸/S10 文件头闸/S13 质量闸**不扩**到 sim/probe/tests(三层存量只读数实跑≈2162 处,其中禁调试打印 274+循环内 await 70 属工具码功能需要;产品码两面现归零,扩面即毁执法前提),改为在 code-conventions §4 新增第 13 条把适用域按来源写清(tests→闸00/01/02、probe→闸03/04/05〔含两件不入闸的人工取证件与共用面〕、sim→不入 CI 的手动调参批量),并停用「测量面」对该三目录的统称(保留 run_all_gates 选闸原义);**S1/S2 随机闸同样不扩**——三目录自建随机源显式定种属合法测量口径,禁的不定种形态改由文字纪律+独立验收审计承载(用户令:说明写规约,不写 README)。②**S13 豁免存废**——结案销号:审计时点三处豁免已于 2026-10-31 迭代 44 批后收尾清偿(基线现 5 键只降不升,commit 9eedf896),本组无对象可裁、不再叠清偿期限。③**零测试点名**——定性改判为「无按文件登记的惯例」而非「没测」(11 件零点名件全有行为断言,只是不经类名;读数由审计的 4 件订正为 11 件,其中三件是迭代 44/46/49 拆件产物=复发模式);立每 core 件点名闸与补点名套件两案裁否(撞 test-conventions §7「覆盖率不是目标」),改为落 test-conventions §8.3「新增 core 件的覆盖登记义务」+process-conventions §3 第 6 条承接指向。**已落地闸件(工程改动,零卡片,用户令在本会话车道内直改)**:static_scan.sh 的 S8 加 settlement/ 目录域反向对账+S7/S8 两份 14 文件清单并成单点 `B1_SET`+「10 个 .gd」文案改派生计数;audit_type_hints.py/audit_file_headers.py 各补扫描面空转自检;architecture S 表 S8 行与 S9/S10 偏差句同批同步。验证=static_scan 全量 13 条规则绿退出码 0、两件负证返回 1、合回后远端 CI `66407117` green。 - #### 三关色相 × 五组微光互辨抽测——三关图类型色板终值冻结的前置抽测(2026-10-28 登记,来源=会话提及) -**实况**:三关图类型色板(`tile_closed` 与 `wall_ambient` 两槽)的终值冻结前,须先跑一次「三关色相 × 五组类型微光」互辨抽测——格底与类型微光同在未开格面上,邻近色相有吞没风险。`design/art/art-bible.md` §6.3 共同纪律已把该抽测立为终值取值程序的第一条:先抽测、再按 §4.3 现行规则重跑 §1.4 格子样张冻结,色值不代填。三关方向候选现行=暖石棕/灰白蓝/灰黑+矿脉金属色;五组微光色带=芥末黄/黄绿/青/紫罗兰/绯红(§4.2),抽测要把这两组逐一交叉比对。本条由 2026-10-28 战斗一屏样张目标规格设计轮的 A-3 定值派生——该轮裁定不沿用方向候选直接定终值,先跑抽测。 - -关联文档清单: -- 相关文档 [美术圣经](design/art/art-bible.md) v3.22(2026-10-28)——§6.3 终值取值程序登记行(本抽测的挂点)与三关方向候选行、§4.2「类型微光色带」条(五组色相 + 明度双码)、§4.3 图类型四槽与不变槽、§1.4 格子样张(终值冻结闸) -- 设计轮依据:2026-10-28 战斗一屏样张目标规格设计轮 §8.1 A-3 条(该轮过程稿已按「吸收即死」删除、不入库,定值与推导沿革见 commit 50702ea5) -- 抽测方案(过程稿):reports/提案-三关色相互辨抽测方案-2026-10-29.md(2026-10-29,取样面/互辨判据/产物形态三件定值与执行步骤 S1–S7) - -**2026-10-29 美术设计段闭合**:三件缺口全部定稿,待裁点 0 条。①取样面=3 关 × 5 组=15 对,每对铺 3 格(素砖底/装饰变体 A/装饰变体 B)=45 取样格,另每关每底型 1 格无微光基准=9 格,合计 54 格;画布 640×1120,正图段+灰度副本段;装饰变体底**带**、迷雾记忆态底**不带**(§4.2/§4.6.3/§6.5 三者合起来永不同格)。②判据=目检四条+机检四条并用,沿 §1.4 已立闸形「目检先行、机检冻结」;机检阈值全部取自本作在役值(合成对比 ≥1.20、格底-微光三通道差不得全部 <8/255、样图读数与合成模型差 ≤±2/255、铺底值准入 L≥0.30/饱和 ≤0.55/避 300°–345°),**色相通道刻意不设机检阈值**(圣经无色相差门槛条文,自造等于把观感问题伪装成可机检问题)。③产物形态=**两者兼有**(并列样图承担目检、逐对读数表承担机检与回归),故改动面须补「美术素材」与「工具代码」两档。新增色值 **0 枚**——`tile_closed`/`wall_ambient` 属 §4.1 分层②场景环境子板,**不占 48 token 额度**,故「额度用尽」不构成阻塞;三关瓦片色表已在役(`tools/recolor_terrain_tiles.py` 的 `PALETTES`,每套 23 色 ≤32),终值从墙顶受光档槽取即可。执行前提已核:三关瓦片现件(dungeon/underdark/deep_underdark 三套)在本机 `game/assets/art/board/` 齐备,可开跑。 +**实况**:三关图类型色板(`tile_closed` 与 `wall_ambient` 两槽)终值冻结前须先跑「三关色相 × 五组类型微光」互辨抽测(格底与类型微光同在未开格面,邻近色相有吞没风险);美术设计段已闭合——取样面 54 格(3 关 × 5 组 × 3 底型+9 基准格)、判据=目检四条+机检四条(阈值全取在役值,色相通道不设机检阈值)、产物=并列样图+逐对读数表两兼。执行步骤与三件定值全载抽测方案过程稿 reports/提案-三关色相互辨抽测方案-2026-10-29.md;抽测挂点=[美术圣经](design/art/art-bible.md) v3.22 §6.3 终值取值程序第一条(终值冻结闸=§1.4 格子样张重跑)。执行前提已核:三关瓦片三套在本机 `game/assets/art/board/` 齐备,可开跑。 **改动面**:文档+美术素材+工具代码 **状态**:美术设计已闭合+待执行 -#### 验证与清单体系整改——四方向分阶段推进(2026-10-28 登记,来源=会话提及) - -**实况**:用户裁「验证及清单不合理」,经调研定四方向全做、分阶段推进:A 粒度整改(清单从断言级升到能力/行为级,逐断言账本退役)→ B 精简裁断(在新粒度上规则驱动删并)→ C 流程风险分级(P0/P1/P2 验收强度、审计抽样)→ D 文档减肥(待办条目限长、历史归 git);测试有效性度量暂不处理。阶段 0 盘点已毕:验证集清单零机器闸依赖(run_all_gates/hooks/五技能均不引用,仅 test-conventions §8.3 维护锚+2 份过程报告引用),退役无闸改动;但测试名尾缀仅覆盖 28/47 个有断言文件(19 个零尾缀,含 seal_polarity 69 条、variant_placement 42 条、roll_multiplier 35 条),故能力清单只能按「能力→代表用例」建,不要求逐断言尾缀。对照表列改动触 pipeline_gate+req-card/iter 两技能;待办正文压缩不触机检(无长度判据)。盘点明细见 reports/盘点-验证与清单体系-2026-10-28.md。**阶段 1 设计已闭合(2026-10-28 用户四裁点)**:能力清单 v1 落 `game/tests/README.md`——按系统归属与玩家旅程排序,首期核心四域(存档与随机、冒险循环、战斗结算、奖励与经济)29 行+跨域条件闸 1 行,共 30 行,每行真实入口+2–3 个代表用例(`文件:函数`),维护规则为每批收口核对本批受影响行并刷新「最后验证批次」;`design/engineering/test-conventions.md` §8.3 维护锚改写为「验证集清单整册冻结、能力清单承接覆盖索引、阶段 2 精简后删除」;`game/tests/验证集清单.md` 头注同步冻结声明,冻结快照(基点 `b9260138`/1587 条)留作阶段 2 对账基准;`tools/extract_checks.py` 保留为审计工具,不再承担常态同步。**阶段 2 已执行闭合(2026-10-28 C 档合回)**:存量断言精简 C 档 6 组手写断言族并为 7 个表驱动站点(33→7),冻结清单对账 1587→1561,验证集清单随阶段 2 完成退役(覆盖索引归能力清单,维护锚 test-conventions §8.3),删并申报与件核见 reports/工程改动报告-存量断言精简C档-2026-10-28.md;阶段 3–4 待各自设计推进:风险分级与审计抽样规则、条目限长是否入 pipeline_gate 均未定。**2026-10-29 阶段 1 落地定稿(用户三裁)**:①能力清单与覆盖域表落 `game/tests/README.md`,独立成表、不与 GDD 验收标准合并;②GDD 纯度判红——系统与概念文档全文禁写实现细节(代码路径/测试文件名/断言名),唯一例外=配置文件索引(`game/data/tables/*.tres` 表路径与表名);③能力清单维护归写卡段——写需求卡片时增删能力行并刷新「最后验证批次」,实现批禁写该文件(清单按规则滞后一个迭代,属设计后果)。三层模型(验收意图/覆盖索引/执行证据)与四法则落 test-conventions §8.9;落地分五批:①三份规约+AGENTS.md 红线+本条实况(本批);②README 覆盖域表+三域能力行补齐;③`tools/capability_audit.py` 文档域新闸(3a 普通工具入库/3b 接闸+基线,worktree);④pipeline_gate 对照表加「能力行」列+req-card/iter 两技能同步;⑤GDD 存量实现细节清理(28 篇约 98 处,逐处去向表过用户目后落笔)。**2026-10-29 阶段 1 五批全部落地**:①032d923c;②5377b2ce;③`tools/capability_audit.py` 入库 ae3c99e3+接闸上电 915222fa(文档域闸 08e 能力审计,纯度红清零后才上电);④f3263444;⑤GDD 清理 00312e12(30 篇去 124 处实现指证,纯度红 124→0)。阶段 1 收口;阶段 3–4 待各自设计推进。 - -**改动面**:文档+游戏代码+工具代码 - -**状态**:文档设计已闭合 - #### 数值标定窗口总挂账——原九条数值类条目合并(2026-10-28 登记,来源=会话提及) -**实况**:2026-10-28 用户令把九条数值类挂账合并为一条:削弱档位的最终数值/迭代 10 奖励重构联动欠账/调参批数值点评登记/三方向各自的解锁清单与定价/GP 经济换算失衡/天赋树实装批登记欠账余两件/商店独立刷新机制两参数/基线通关率越带加难杠杆扫描/成长系数节奏——原九条同步删除,内容全量迁入汇总文档,git 历史可考(本提交)。共同背景:M4 数值批卡已随 2026-10-16 删卡令退役;2026-10-18 用户裁=各条留待办清单、未设计未启动、不另行归属,未来数值标定窗口重开时重走设计段再写卡——本条沿用该裁定,重启条件=用户发令开窗口。合并动机=九条共享同一重启条件与同一执行形态(窗口内一次 MC 批量统一覆盖各条对比需求:全冒险期望+奖励期望),分散登记徒增维护面。逐条挂账明细、裁定史与相关文档见汇总文档。 - -关联文档清单: -- 汇总文档 reports/汇总-数值标定窗口挂账-2026-10-28.md(2026-10-28,九条全量内容+统一执行形态建议序:设计段逐条裁决→按域拆卡→实现批三处同步→测量批一次跑批) -- MC 采集档位表 sim-data/README.md(档位硬闸与执行约束:一档只能由用户发起、无数值改动零跑) +**实况**:2026-10-28 用户令把九条数值类挂账(削弱档位终值/迭代 10 奖励重构联动/调参点评登记/三方向解锁清单与定价/GP 经济换算失衡/天赋树欠账余两件/商店刷新两参数/基线通关率越带杠杆扫描/成长系数节奏)合并为一条,内容全量迁汇总文档 reports/汇总-数值标定窗口挂账-2026-10-28.md(逐条明细+统一执行形态:窗口内一次 MC 批量覆盖全冒险期望+奖励期望)。共同裁定(2026-10-18):各条留待办、未设计不启动、重启条件=用户发令开数值标定窗口。MC 档位硬闸见 sim-data/README.md「MC 采集档位表」。 **缺口**:数值标定窗口未重开(用户发令触发);窗口设计段逐条裁决写入文档后方可写卡;其中原「基线通关率越带」条另等真人批 k 系数到账。 @@ -112,9 +87,9 @@ #### 棋盘战斗键盘/手柄输入(2026-10-04 登记,来源=会话提及) -**实况**:战斗棋盘操作现行唯一输入=鼠标——左键已开格=移动/未开格=挖掘,右键=封印(封印印记一次性承诺,无移除手段),悬停承载合法性反馈(可挖域微光 + BFS 路径点迹);全仓无 InputEventKey/JoypadButton 处理,project.godot 无自定义 InputMap 动作。**可行性已核(2026-10-04):可做**——分发接缝现成,board_view `action_requested(cell, kind)`(kind ∈ {dig, move, flag_place, flag_pull})是唯一出口,键盘/手柄作第二输入前端产出同款信号即可,规则引擎合法性校验零改动;Godot InputMap 原生支持键盘与手柄绑定同一动作,与鼠标并存不冲突。用户期望操作形态:十字方向移动;挖掘/封印各一独立键;方向控制选定 8 向挖掘或封印目标(8 向恰与现行可挖域同集,十字移动与立绘 4 向既有裁决一致);键盘移动语义=逐格步进。连带设计点四条(实施批先裁):① 键盘模式需屏上光标格承载现行悬停反馈;② 键盘默认键位与手柄键位映射待定;③ 弹层界面(结算/三选一/商店/设置等)现行全鼠标,手柄全覆盖需焦点导航——是否同批待裁(2026-10-06 增补:暂停层〔现状态面板〕Esc 快捷通道并入本条随键盘批统一实施,弹层清单 +1 项);④ 键位自定义是否进设置面待裁。排期 Beta(2026-10-04 登记;可行性已核毕,立项时按 roadmap 开卡)。 +**实况**:战斗棋盘现行唯一输入=鼠标;键盘/手柄作第二输入前端可做(可行性已核 2026-10-04)——分发接缝现成,board_view `action_requested(cell, kind)` 唯一出口,规则引擎合法性校验零改动,Godot InputMap 原生支持与鼠标并存。用户期望形态:十字方向逐格移动、挖掘/封印各一独立键、8 向选定挖掘或封印目标;排期 Beta(立项时按 roadmap 开卡)。 -**缺口**:还差 Beta 立项时的输入方案设计讨论——四个连带裁决点(光标反馈承载/键位映射/弹层焦点导航范围/键位自定义)先裁再开卡。 +**缺口**:还差 Beta 立项时的输入方案设计讨论——四个连带裁决点先裁再开卡:①键盘模式屏上光标格承载悬停反馈;②键盘与手柄键位映射(暂停层 Esc 快捷通道并入本条);③弹层焦点导航是否同批;④键位自定义是否进设置面。 - 相关文档:[排雷玩法](design/gdd/systems/排雷循环/排雷玩法.md)(动作语义与 8 向目标规则主责)+ [HUD 框架](design/gdd/systems/表现与支撑/HUD框架.md)(键盘光标与合法性反馈呈现)+ [设置与本地化](design/gdd/systems/表现与支撑/设置与本地化.md)(键位自定义,可选面) **改动面**:文档 @@ -186,9 +161,9 @@ #### 第二 / 三关棋盘观感——亮度与对比度(2026-10-13 登记,来源=playnote) -**实况**:来源=playnote 用户试玩记录「UI 优化,第二第三关的棋盘看着太累了;不知道是因为亮度还是对比度的原因,看着非常费劲,非常不舒服」。2026-10-13 用户裁定:**这是需要做的**,且本就属版本标准的覆盖范围——[08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「五 · 表现」已新增「棋盘观感(第二 / 三关亮度与对比度)」行,标待做。**开工前须先定性(沿用既有裁决)**:是**素材轴**问题(棋盘瓦片与格面图标本身的明度与色相),还是 **UI 轴**问题(舞台底色与叠加层的对比关系)——两轴修法完全不同,定性错了等于白改一轮;该定性要求(原备忘 (e) 项)是本条的开工前置。2026-10-16 曾编入迭代 30 卡③(UI 呈现三卡批序位③),2026-10-17 用户裁定剔除回待设计(自身挂「素材轴/UI 轴」定性人闸+甲/乙〔recolor/远程生图重产〕素材裁点;若裁乙,其瓦片规格依赖战斗一屏样张批的目标规格清单产出)。v1.4 旧卡留 reports/需求卡片-二三关棋盘观感批-2026-10-16.md 作素材,非已写卡状态。与已完成注销的「呈现层残余 <4.5:1 文字位」分工:本条管**棋盘区域整体的观感**(亮度/对比度/费劲感,体感问题),彼条管**具体文字位的对比度读数**(机检可判硬指标),两条不同面不互相替代。Alpha 出口裁决:Alpha 必须,先做素材轴/UI 轴对照定性;出口=用户实机目检不再判「看着费劲」。 +**实况**:来源=playnote 试玩记录「第二第三关棋盘看着费劲」;用户裁定要做,[08-Alpha版本标准](design/gdd/08-Alpha版本标准.md)「五 · 表现」已立行标待做。2026-10-16 曾编入迭代 30 卡③后剔除回待设计;v1.4 旧卡 reports/需求卡片-二三关棋盘观感批-2026-10-16.md 在册但非已写卡状态。分工:本条管棋盘区域整体观感(亮度/对比度/费劲感,体感问题),与已注销的「呈现层残余 <4.5:1 文字位」条(机检硬指标)不同面不互代。Alpha 出口=用户实机目检不再判「看着费劲」。 -**缺口**:还差「素材轴 / UI 轴」定性设计讨论与甲/乙素材裁点裁决;素材轴若走重产,还依赖战斗一屏样张批的目标规格清单产出。旧卡 v1.4(reports/需求卡片-二三关棋盘观感批-2026-10-16.md)在册但非已写卡状态,其前置未完成三件:①「素材轴 / UI 轴」定性未做,这是既有条款规定的开工前置;②甲(recolor 现瓦片)/乙(远程生图重产)素材裁点未裁;③若裁乙,瓦片规格压在样张批的目标规格清单上——该清单已随战斗一屏样张批落定(art-bible v3.22 五张规格表,2026-10-30 合回)。 +**缺口**:还差「素材轴 / UI 轴」定性设计讨论与甲(recolor 现瓦片)/乙(远程生图重产)素材裁点裁决——定性是既有条款的开工前置;素材轴若走重产,依赖战斗一屏样张批目标规格清单(已随 art-bible v3.22 落定)。 - 相关文档:[HUD框架](design/gdd/systems/表现与支撑/HUD框架.md)(UI 轴:舞台底与叠加层)+ [美术圣经](design/art/art-bible.md)(素材轴:瓦片与格面图标的明度色相)——定性前两方共裁 **改动面**:美术素材+游戏代码 @@ -219,22 +194,9 @@ #### 棋盘封印印记图形换代——现件仍是扫雷旗形,改法阵或锁链待设计(2026-10-30 登记,来源=会话提及) -**实况**:用户口径=棋盘封印图标现在还是按旧扫雷的做法画成一个旗子,希望换成法阵那样的封印、或锁链;形未定,先做设计讨论再出图。现状证据: +**实况**:用户口径=封印图标现为扫雷旗形,改法阵或锁链待设计,形未定先做讨论。现件 `game/assets/art/board/seal_mark.png`(32×32 旗形剪影);消费面两处——棋盘封印槽绘制(`tile_palette.gd:19` → `board_view.gd:616`)与战末金蜡封徽记(`battle_end_overlay.gd:65-69` 复用同图);「旗」概念已全库退役(2026-10-18),文档口径仍以旗为形待换代:[美术圣经](design/art/art-bible.md) v3.23 §3.2/§4.1、[美术资源依赖清单](design/art/art-assets-checklist.md) §3.3/§4、[战斗屏 UX](design/gdd/ux/battle.md) :128/:270、[体验验证清单](体验验证清单.md) 第 4 条。 -- 现件 `game/assets/art/board/seal_mark.png`(32×32 纯黑剪影)=经典扫雷旗形(旗面 + 旗杆)。2026-09-28 那次只定了色(旗朱→封印紫→封印黑 `#000000`),图形一直没动。 -- 消费面两处,换形同时受影响:棋盘侧 `game/presentation/views/tile_palette.gd:19`(`TILE_SEAL_MARK` 常量)→ `board_view.gd:616` 未开格封印槽绘制,盘上缺图时回落单字「封」(`board_view.gd:654-658`);战末弹层的「金蜡封徽记」复用同一张图(金底 52×52 面板 `battle_end_overlay.gd:65-69`,叠 32px 印记 `:84`)——蜡封徽记要不要跟着换是独立一裁。 -- 文档侧口径仍以旗为形:art-bible §4.1 封印黑条内含「旗杆米白保可读」这一旗形前提、§3.2 封印印记条只锁色与格内栈位;art-assets-checklist §4 封印特效行写「印记旗面走封印黑」「印记常显形态可与 §3.3 旗面像素化合并出」;ux/battle.md:128 呈现术语注记与 :270 悬停三态光标「封印(印记形)」。 -- 术语层已闭合,本条只欠呈现层:「旗」概念 2026-10-18 用户裁全库退役(动作=封印、印记=封印印记、板面单字=「封」),图形停在退役前的形态。 - -关联文档清单: -- 相关文档 [美术圣经](design/art/art-bible.md) v3.23——§3.2 封印印记条(:167)· §4.1 封印黑条(:202)· §1.2 格内优先级栈 · §1.4 格子样张 -- 相关文档 [美术资源依赖清单](design/art/art-assets-checklist.md)——§3.3 雷/封印印记/数字格面像素化(:118)· §4 封印特效行(:162) -- 相关文档 [美术素材状态清单](design/art/art-status-checklist.md)——P2「雷/封印印记/数字砖面全套」◐ · P3「封印特效」⬜ -- 相关文档 [战斗屏 UX](design/gdd/ux/battle.md)(Last Updated 2026-10-29)——:128 呈现术语注记 · :270 悬停预承诺三态光标 · :261 未开格封印交互行 -- 相关文档 [术语表](design/gdd/术语表.md) v1.25——「封印」条(:15)· 用语规范禁用字面条(:184) -- 相关目检项 [体验验证清单](体验验证清单.md) 第 4 条「封印印记贴图三关加载」(:317,现判据只验贴图是否加载、不验形状) - -**缺口**:还差一次封印印记图形的设计讨论(形未定,法阵/锁链两案并列,禁代裁),讨论须一并裁五点:①形=法阵(圆形阵纹)还是锁链(束缚感),或第三种方案;与危险格巢穴纹、奖励徽章的剪影语言(art-bible §3.1 直线几何体)互辨是否成立。②色=现封印黑 `#000000` 是 §4.1 不变槽成员,法阵若带发光或色相即与该条口径冲突,须重登记不变槽与对比度机检判据(现判据=未开格墙顶对纯黑 ≥4.4:1)。③尺寸与遮挡=32×32 内保持可读,格内优先级栈「数字 > 小人 > 封印印记」下法阵铺满整格是否侵入数字字形区(§3.2 验收句禁止)。④连带件=战末金蜡封徽记与悬停「封印(印记形)」光标是否同步换,还是各留一件。⑤与「封印特效=施印瞬间特效 + 印记常显形态」两件的关系=合并出一件还是分两件。裁决写入 art-bible §3.2/§4.1 与两份美术清单条款后,才可出样张与终稿(终稿文件名沿用代码消费名 `seal_mark.png`,除非裁决换名)。 +**缺口**:还差封印印记图形设计讨论(法阵/锁链两案并列,禁代裁),须一并裁五点:①形(与危险格巢穴纹、奖励徽章剪影语言 art-bible §3.1 互辨);②色(法阵带发光/色相与 §4.1 封印黑不变槽冲突,须重登记判据);③尺寸遮挡(32×32 内「数字 > 小人 > 封印印记」栈位不侵入数字字形区);④金蜡封徽记与悬停「封印(印记形)」光标是否同步换;⑤与封印特效两件(施印瞬间/常显形态)合并或分立。裁决写入 art-bible §3.2/§4.1 与两份美术清单后方可出样张(终稿名沿用 `seal_mark.png`)。 **改动面**:文档+美术素材 @@ -299,9 +261,9 @@ #### 「生涯」界面——冒险中数据回看的唯一承接处(2026-10-04 登记,来源=会话提及) -**实况**:2026-10-04 用户裁决(UI 落码计划 P-C7)——冒险中不给数据回看:settlement_review_overlay(结算明细回看)与结算框「明细回看」钮在冒险中退役,战报带只留单行「上轮」;历史战报/结算明细的查看去向=新「生涯」界面(跨局汇总/历史冒险回看/图鉴承接)。来源=UI 重设计原型 v2 落码计划裁决记录(已退役,git 历史可查 §七)。**设计提纲已成文**:[systems/跨局循环/生涯.md](design/gdd/systems/跨局循环/生涯.md) v0.1 范围草案五节成文〔信息架构/承载内容清单/与既有界面关系/分期实装建议/待裁点〕,P0-P5 六裁点已全裁并写入文档〔P0甲 提纲落现行事实源 / P1甲 主菜单一级入口 / P2甲 每局一行摘要+cap 扩容 N+补用时埋点 / P3甲 敌人图鉴优先 / P4甲 局内不放入口+生涯零跳转 / P5甲 settlement_review 复活承接〕。**期一已落地**(2026-10-07 迭代 18 卡④实装批:生涯页六类九项+主菜单入口+终身计数域存档 v6,批末全量域闸全绿;实机人闸=体验验证清单⑲ 生涯页目检节)。剩余面=期二(历史回看/图鉴)与期三实装+P6 营地最近冒险条带去留(新发现待裁点,随提纲评审一并裁)。**迭代 19 卡②遗留件(2026-10-08 登记)**:settlement_review_overlay.gd 现态考证=未接线遗留件(全仓零引用,M9 结算框改版「明细回看」钮退役后遗留)——处置两途:①随生涯实装批按 P5 甲复活承接(重接线入生涯);②确认不再需要则正式退役删除文件;二选一归生涯实装批/用户裁。Alpha 出口裁决:期二、期三全部排 Beta——Alpha 只保留期一,不在 Alpha 内做生涯新内容。 +**实况**:2026-10-04 用户裁决(UI 落码计划 P-C7)——冒险中不给数据回看,历史战报/结算明细查看去向=新「生涯」界面;settlement_review_overlay 与「明细回看」钮在冒险中退役,战报带只留单行「上轮」。设计提纲已成文并全裁:[systems/跨局循环/生涯.md](design/gdd/systems/跨局循环/生涯.md) v0.1(P0–P5 六裁点已写入文档)。期一已落地(2026-10-07 迭代 18 卡④:六类九项+主菜单入口+终身计数域存档 v6)。遗留件:settlement_review_overlay.gd 未接线全仓零引用(迭代 19 卡②登记),处置两途=①随期二按 P5 甲复活承接/②确认不需要则退役删除,归生涯实装批/用户裁。 -**缺口**:还差提纲用户评审收尾与 P6 营地最近冒险条带去留裁决——裁完才能立期二/期三实装卡(期一已交付,期二/三未预占排期)。本条排 Beta,不阻塞 Alpha;重启时再补 P6 与 N 终值。 +**缺口**:还差提纲用户评审收尾与 P6 营地最近冒险条带去留裁决——裁完才能立期二/期三实装卡(期一已交付);本条排 Beta,Alpha 只保留期一。 **改动面**:文档 @@ -311,9 +273,7 @@ #### EffectPort biz_fact 键 charge_layers——无属主数据游离出领域实体的处置(2026-11-02 登记,来源=审计发现) -**实况**:证据=reports/审计-全库架构审查-2026-10-29.md §3.1 B 类第 2 行(`CHARGE_LAYER_CAP` 自标「机制结构常量」)+`game/core/effect_port.gd:4`(biz_fact 闭面五键声明)+`game/core/action_economy.gd:14/37/203`(常量、`_charge_layers` 裸账本、transfer 分支唯一写点)。 - -需求卡片 reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md(2026-11-04,v1.0——写卡段代码级复核补全残留面 15 处与词表注释 3 处、transfer 形态无执行体考证、transfer=true 零测试考证;新增考证修正=effect_port_test 实测无 charge_layers 直接断言,V3 闭面组用 hp_ratio/battle_index 两对照行,故验收断言改为 V4「宿主 biz_fact 应答 null」新断言)。2026-11-02 架构审查讨论逐键核闭面:其余四键各有领域实体持有数据(hp_ratio=主角生命、dig_streak=战斗轮次事实、rider_tier 两键=每战复位的战斗事实束),唯 charge_layers 背后是 action_economy 裸账本——全仓零内容件注册「停手转蓄力」订阅(.tres 零命中),damage_controller 三处「厚积薄发/铁壁按层缩放」仅存于代码注释描述的假想订阅面,无任何表行或效果规格实际消费。用户裁决=删除方向,总判据「机制数据一律长在所属封装实体的内部属性(表行字段)里,全局常量与无主账本清零」。处置范围:①闭面五键收窄为四键(charge_layers 键退役、effect_port_test 对应断言同改——触及迭代 49 卡①刚立的端口契约,卡内申报契约改动);②`_charge_layers` 账本、`finish_round_stop` transfer 分支、`charge_full` 事件位、`CHARGE_LAYER_CAP` 常量随键退役;③蓄力周转专长(feats.tres swap_charge_layers 计数器,文档口径「成功刷新攒层」与实现一致)不受影响,写卡时核对其测试面无牵连。 +**实况**:证据=reports/审计-全库架构审查-2026-10-29.md §3.1 B 类第 2 行+`game/core/effect_port.gd:4`(biz_fact 闭面五键)+`game/core/action_economy.gd:14/37/203`(裸账本与唯一写点)。2026-11-02 架构审查逐键核闭面:其余四键各有领域实体持有数据,唯 charge_layers 背后是无主账本(全仓零订阅注册、零表行消费);用户裁决=删除方向,总判据「机制数据一律长在所属封装实体的内部属性(表行字段)里,全局常量与无主账本清零」。需求卡片 reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md(v1.0——处置范围、残留面考证与断言换代申报全载卡内)。 **改动面**:游戏代码 @@ -328,3 +288,11 @@ **改动面**:美术素材 **状态**:待美术设计 + +#### ci_watch 中间态误写终局红回执(2026-11-04 登记,来源=批次移交) + +**实况**:2026-11-04 run 37(commit 536dc072)实证——ci-status.json 于 16:59:55 写入 verdict=red(note=远端CI state=failure, run 37),而该 run 实际 17:03:10 才以「Job succeeded」落定,现查 Gitea API 组合状态=success、run conclusion=success;回执与真值相反,下游按「红未修不开新批」被误阻塞(验收档与条目限长批开工时人工查 API 解封)。证据=job 日志结尾「Job succeeded」(Gitea API actions/jobs/38/logs)+commits/536dc072/status 现查 success。修复方向=轮询只认 run conclusion 落定后的终局态(pending/中间态不写盘继续等)。 + +**改动面**:工具代码 + +**状态**:待执行 From 06d915d6cc774872dc970352bf3dc0eda755fba1 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 4 Nov 2026 01:57:14 +0800 Subject: [PATCH 17/19] =?UTF-8?q?=E5=B7=A5=E7=A8=8B(=E5=9B=BE=E9=89=B4?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=C2=B7=E9=87=87=E9=9B=86=E7=AB=AF=E4=B8=8E?= =?UTF-8?q?=E6=B8=B2=E6=9F=93=E7=AB=AF=C2=B7=E7=94=A8=E6=88=B7=E4=BB=A4):?= =?UTF-8?q?=20compendium=5Fdump=E7=BB=8FConfigDB=E5=AF=BC=E5=87=BAenemy+sk?= =?UTF-8?q?ills=E5=85=A8=E8=A1=8CJSON(out/tables=5Froot=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E5=8C=96)+compendium=5Fgen=E7=94=9F=E6=88=90=E8=87=AA=E5=8C=85?= =?UTF-8?q?=E5=90=ABHTML=E5=9B=BE=E9=89=B4(=E6=8C=89=E5=85=B3=E6=8C=89?= =?UTF-8?q?=E5=B8=A6=E5=88=86=E7=BB=84=C2=B7=E6=B1=A0=E4=BB=BD=E9=A2=9D?= =?UTF-8?q?=C2=B7=E6=8A=80=E8=83=BD=E8=AF=AD=E4=B9=89);=20=E5=AF=B9?= =?UTF-8?q?=E8=B4=A6=E4=B8=89=E4=BB=B6=E8=BF=87+=E6=82=AC=E7=A9=BA?= =?UTF-8?q?=E5=BC=95=E7=94=A8fail-fast=E9=9D=9E=E9=9B=B6=E9=80=80=E5=87=BA?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E8=BF=87+=E7=BB=93=E6=9E=84=E5=AE=A1?= =?UTF-8?q?=E8=AE=A1PASS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game/sim/compendium_dump.gd | 108 ++++++++++++++ game/sim/compendium_dump.gd.uid | 1 + tools/compendium_gen.py | 248 ++++++++++++++++++++++++++++++++ 3 files changed, 357 insertions(+) create mode 100644 game/sim/compendium_dump.gd create mode 100644 game/sim/compendium_dump.gd.uid create mode 100644 tools/compendium_gen.py diff --git a/game/sim/compendium_dump.gd b/game/sim/compendium_dump.gd new file mode 100644 index 00000000..c30c0206 --- /dev/null +++ b/game/sim/compendium_dump.gd @@ -0,0 +1,108 @@ +## 怪物图鉴外置工具·采集端:经 ConfigDB 单点读 enemy + skills 两表全行,行数据原样导出 JSON +## 到 sim-data/compendium/dump.json(渲染端 tools/compendium_gen.py 消费,生成自包含 HTML 图鉴)。 +## 运行:Godot_console.exe --headless --path . --script res://sim/compendium_dump.gd -- [out=<绝对路径>] [tables_root=] +## out 缺省 = 仓库根 sim-data/compendium/dump.json(res:// 的上一级);目录不存在则创建。 +## tables_root 缺省 = res://data/tables;fail-fast 路径验证时可指向临时表目录。 +## 导出形态:顶层 counts 带两表行数计数 + enemy_rows/skill_rows 行字典原样(零新增字段、零改名; +## 表内可省略字段缺席即缺席)。本件零随机、零数值硬编码、零判定逻辑。 +## fail-fast:表加载失败(缺表/行域校验/跨表悬空引用)、行缺关键字段、pool.skill_id 在技能表无对应行 +## → 逐条报错并以退出码 1 中止,禁软回退。 +extends SceneTree + +const DEFAULT_OUT := "../sim-data/compendium/dump.json" # 相对 res://(game/ 上一级 = 仓库根) +const DEFAULT_TABLES_ROOT := "res://data/tables" + +# 行关键字段(缺一即 fail-fast):取两表 schema 加载期必在的键—— +# enemy 的 unit_count_max/atk_min/atk_max/attack_type/armor_type/armor_class 与技能行的 +# trigger/buff_ref/buff_duration/damage_mult/rider_mult 均为 schema 可省略字段,不列入。 +const ENEMY_REQUIRED_KEYS := ["enemy_id", "display_name", "row_kind", "level_index", "depth_band", "unit_count", "hp", "atk", "pool"] +const SKILL_REQUIRED_KEYS := ["skill_id", "display_name", "type", "cooldown_beats"] + + +func _initialize() -> void: + var opt := _parse_args(OS.get_cmdline_user_args()) + var db = load("res://core/config_db.gd").new() + if not db.load_tables(String(opt.tables_root), false): + _print_diags(db) + push_error("compendium_dump: 表加载失败(fail-fast)") + quit(1) + return + var enemy_rows: Array = db.combat.enemy.rows + var skill_rows: Array = db.combat.skill.rows + var errs := _validate_rows(enemy_rows, skill_rows) + if not errs.is_empty(): + for e in errs: + push_error("compendium_dump: %s" % e) + quit(1) + return + var payload := { + "counts": {"enemy_rows": enemy_rows.size(), "skill_rows": skill_rows.size()}, + "enemy_rows": enemy_rows, + "skill_rows": skill_rows, + } + var out_path := String(opt.out) + var dir := out_path.get_base_dir() + if not DirAccess.dir_exists_absolute(dir): + var mk := DirAccess.make_dir_recursive_absolute(dir) + if mk != OK: + push_error("compendium_dump: 目录创建失败 %s(err=%d)" % [dir, mk]) + quit(1) + return + var f := FileAccess.open(out_path, FileAccess.WRITE) + if f == null: + push_error("compendium_dump: 导出文件打开失败 %s(err=%d)" % [out_path, FileAccess.get_open_error()]) + quit(1) + return + f.store_string(JSON.stringify(payload)) + f.close() + print("图鉴导出完成: enemy_rows=%d skill_rows=%d → %s" % [enemy_rows.size(), skill_rows.size(), out_path]) + quit(0) + + +func _parse_args(args: PackedStringArray) -> Dictionary: + var opt := {"out": "", "tables_root": DEFAULT_TABLES_ROOT} + for a in args: + var kv := String(a).split("=", true, 1) + if kv.size() != 2: + continue + if kv[0] == "out": + opt["out"] = String(kv[1]) + elif kv[0] == "tables_root": + opt["tables_root"] = String(kv[1]) + if String(opt.out).is_empty(): + opt["out"] = ProjectSettings.globalize_path("res://").path_join(DEFAULT_OUT) + return opt + + +# 行面 fail-fast 校验:关键字段在位 + pool.skill_id 引用闭合(技能表行集先建索引再对账) +func _validate_rows(enemy_rows: Array, skill_rows: Array) -> Array: + var errs: Array = [] + var skill_ids := {} + for row_v in skill_rows: + var row: Dictionary = row_v + var sid := String(row.get("skill_id", "")) + if sid.is_empty(): + errs.append("技能行缺 skill_id") + for k in SKILL_REQUIRED_KEYS: + if not row.has(k): + errs.append("技能行 %s 缺关键字段: %s" % [sid, k]) + skill_ids[sid] = true + for row_v in enemy_rows: + var row: Dictionary = row_v + var eid := String(row.get("enemy_id", "")) + if eid.is_empty(): + errs.append("敌行缺 enemy_id") + for k in ENEMY_REQUIRED_KEYS: + if not row.has(k): + errs.append("敌行 %s 缺关键字段: %s" % [eid, k]) + for entry_v in row.get("pool", []): + var entry: Dictionary = entry_v + var sid := String(entry.get("skill_id", "")) + if not skill_ids.has(sid): + errs.append("敌行 %s pool 引用不存在的 skill_id: %s(悬空致命)" % [eid, sid]) + return errs + + +func _print_diags(db) -> void: + for d in db.diagnostics(): + print("[ConfigDB/%s] %s: %s" % [d.category, d.severity, d.message]) diff --git a/game/sim/compendium_dump.gd.uid b/game/sim/compendium_dump.gd.uid new file mode 100644 index 00000000..2300a34a --- /dev/null +++ b/game/sim/compendium_dump.gd.uid @@ -0,0 +1 @@ +uid://bnbug3wg477av diff --git a/tools/compendium_gen.py b/tools/compendium_gen.py new file mode 100644 index 00000000..c81b918e --- /dev/null +++ b/tools/compendium_gen.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""怪物图鉴外置工具·渲染端——读 dump.json,生成自包含 index.html(零判定逻辑,只做组织与呈现)。 + +数据源 = game/sim/compendium_dump.gd 的导出件(enemy + skills 两表行数据原样 + 两表行数计数)。 +组织:按 level_index 分关、关内按 depth_band 分组、组内保持表内行序;每行一张敌种卡—— +显示名 / enemy_id / row_kind / 全部属性行值 / 池构成(技能显示名 + 权重 + 份额)+ 每技能语义 +(类型 / 倍率 / 必中附加分量 / 冷却 / 触发条件 / 增益引用与持续)。 +自包含:纯 python 标准库、内容全部内嵌标记、无外链无网络请求无构建工具链,双击可开; +同路径重复生成直接覆盖。字段名保留英文原文,值尽量用表内中文 display_name 与枚举中文名。 +用法: + python tools/compendium_gen.py # 缺省 dump = sim-data/compendium/dump.json,输出同目录 index.html + python tools/compendium_gen.py --dump <路径> --out <路径> +fail-fast:dump 缺失 / JSON 损坏 / counts 与实际行数不符 / 行缺展示必需字段 / 池引用悬空 +→ 报错退出码 1,禁软回退。 +""" +import argparse +import json +import sys +from html import escape +from pathlib import Path +from typing import NoReturn + +ROOT = Path(__file__).resolve().parent.parent +DEFAULT_DUMP = ROOT / "sim-data" / "compendium" / "dump.json" +DEFAULT_OUT = ROOT / "sim-data" / "compendium" / "index.html" + +# 展示必需字段(dump 采集端 fail-fast 契约的对应面;缺一即死) +ENEMY_REQUIRED = ("enemy_id", "display_name", "row_kind", "level_index", "depth_band") +SKILL_REQUIRED = ("skill_id", "display_name", "type", "cooldown_beats") + +# 以下中文名均为表 schema 封闭枚举的展示词(enemy_table.gd / skill_table.gd),非玩法数值 +LEVEL_CN = {1: "第一关", 2: "第二关", 3: "第三关"} +ROW_KIND_CN = {"battle": "战斗行", "boss": "Boss行"} +ATTACK_TYPE_CN = {"normal": "普通", "pierce": "穿刺", "magic": "魔法"} +ARMOR_TYPE_CN = {"light": "轻甲", "ward": "魔法护甲", "heavy": "重甲"} +SKILL_TYPE_CN = {"basic": "普攻", "damage": "伤害", "buff": "增益", "debuff": "妨害"} +TRIGGER_FACT_CN = { + "self_hp_pct": "自身血量%", "hero_hp_pct": "主角血量%", "round_index": "回合序号", + "last_round_end": "上轮结束", "mines_hit_last": "上轮踩雷数", "mines_hit_total": "累计踩雷数", +} +TRIGGER_OP_CN = {"eq": "==", "neq": "≠", "gt": ">", "gte": "≥", "lt": "<", "lte": "≤"} + +FIELD_CN = { + "level_index": "关卡", "row_kind": "行类", "depth_band": "深度带", "enemy_id": "敌种ID", + "display_name": "显示名", "unit_count": "单位数", "unit_count_max": "单位数上限", + "hp": "生命", "atk": "攻击基线", "atk_min": "攻击下限", "atk_max": "攻击上限", + "attack_type": "攻击类型", "armor_type": "护甲类型", "armor_class": "护甲等级", + "skill_id": "技能ID", "type": "类型", "damage_mult": "伤害倍率", "rider_mult": "必中附加分量", + "cooldown_beats": "冷却拍数", "trigger": "触发条件", "buff_ref": "增益引用", "buff_duration": "增益持续", +} + + +def die(msg: str) -> NoReturn: + print(f"[compendium_gen] FAIL:{msg}", file=sys.stderr) + sys.exit(1) + + +def esc(v) -> str: + return escape(str(v), quote=True) + + +def enum_cn(table: dict, key: str, cn_map: dict) -> str: + """枚举值 → 「中文名 (raw)」;未知枚举原样展示(fail-fast 只拦必需字段,展示层不发明)""" + raw = table.get(key, "") + cn = cn_map.get(raw) + return f"{cn} ({raw})" if cn is not None else str(raw) + + +def level_cn(level_index) -> str: + try: + n = int(level_index) + except (TypeError, ValueError): + return esc(level_index) + return LEVEL_CN.get(n, f"第{n}关") + + +def trigger_desc(trig) -> str: + if not isinstance(trig, dict): + die(f"trigger 字段须为字典,实际: {trig!r}") + fact = trig.get("fact", "") + op = trig.get("op", "") + parts = [f"{TRIGGER_FACT_CN.get(fact, fact)} {TRIGGER_OP_CN.get(op, op)} {trig.get('value', '')}".strip()] + if trig.get("latch"): + parts.append("一次性(latch)") + return " · ".join(parts) + + +def skill_semantics(srow: dict) -> str: + bits = [enum_cn(srow, "type", SKILL_TYPE_CN)] + if "damage_mult" in srow: + bits.append(f"倍率 ×{srow['damage_mult']}") + if "rider_mult" in srow: + bits.append(f"必中附加 ×{srow['rider_mult']}") + bits.append(f"冷却 {srow.get('cooldown_beats', '?')} 拍") + if "trigger" in srow: + bits.append(f"触发: {trigger_desc(srow['trigger'])}") + if "buff_ref" in srow: + dur = f" · 持续 {srow['buff_duration']}" if "buff_duration" in srow else "" + bits.append(f"增益引用 {srow['buff_ref']}{dur}") + return " · ".join(bits) + + +def attr_value(row: dict, key: str) -> str: + if key == "row_kind": + return enum_cn(row, key, ROW_KIND_CN) + if key == "attack_type": + return enum_cn(row, key, ATTACK_TYPE_CN) + if key == "armor_type": + return enum_cn(row, key, ARMOR_TYPE_CN) + return esc(row[key]) + + +def render_enemy_card(row: dict, skill_by_id: dict) -> str: + eid = row["enemy_id"] + badge = ROW_KIND_CN.get(row["row_kind"], row["row_kind"]) + out = [f'
'] + out.append(f'

{esc(row["display_name"])} {esc(eid)}' + f'{esc(badge)}

') + out.append('') + for key in row: + if key == "pool": + continue + out.append(f'' + f'') + out.append('
{esc(FIELD_CN.get(key, key))} {esc(key)}{attr_value(row, key)}
') + pool = row.get("pool") + if not isinstance(pool, list) or not pool: + die(f"敌行 {eid} pool 缺失或非数组(dump 采集端契约破坏)") + weights = [] + for entry in pool: + if not isinstance(entry, dict) or "skill_id" not in entry or "weight" not in entry: + die(f"敌行 {eid} pool 条目缺 skill_id/weight: {entry!r}") + weights.append(int(entry["weight"])) + total = sum(weights) + if total <= 0: + die(f"敌行 {eid} pool 权重合计非正: {total}") + out.append('' + '') + for entry, w in zip(pool, weights): + sid = str(entry["skill_id"]) + if sid not in skill_by_id: + die(f"敌行 {eid} pool 引用不存在的 skill_id: {sid}(悬空致命)") + srow = skill_by_id[sid] + share = f"{w / total * 100:.1f}%" + out.append(f'' + f'' + f'') + out.append('
技能权重份额语义
{esc(srow["display_name"])} {esc(sid)}{w}{share}{skill_semantics(srow)}
') + return "\n".join(out) + + +CSS = """\ +body{font-family:"Microsoft YaHei",system-ui,sans-serif;margin:2em auto;max-width:60em; + padding:0 1em;color:#222;background:#faf8f4;line-height:1.5} +h1{border-bottom:3px solid #6b5a3e;padding-bottom:.2em} +h2{margin-top:1.6em;color:#4a3b26} +h3{margin:1.2em 0 .4em;color:#5a4a30} +section.enemy{border:1px solid #c9bda5;border-radius:6px;padding:.6em 1em;margin:.8em 0;background:#fff} +section.enemy h4{margin:.2em 0 .5em} +code{background:#efe9dc;border-radius:3px;padding:0 .3em;font-size:.9em} +.badge{float:right;background:#6b5a3e;color:#fff;border-radius:3px;padding:.05em .5em;font-size:.8em} +table{border-collapse:collapse;width:100%;margin:.3em 0} +th,td{border:1px solid #d8cdb8;padding:.25em .6em;text-align:left;vertical-align:top} +th{background:#f1ebdd;white-space:nowrap;font-weight:600} +table.pool th{background:#e7dfd0} +td.sem{font-size:.92em} +p.note{color:#6a5c44;font-size:.92em} +.counts{background:#efe9dc;border-radius:4px;padding:.3em .8em;display:inline-block} +""" + + +def build_html(dump: dict) -> str: + counts = dump.get("counts") + enemy_rows = dump.get("enemy_rows") + skill_rows = dump.get("skill_rows") + if not isinstance(counts, dict) or not isinstance(enemy_rows, list) or not isinstance(skill_rows, list): + die("dump.json 顶层缺 counts/enemy_rows/skill_rows(结构不符)") + if counts.get("enemy_rows") != len(enemy_rows) or counts.get("skill_rows") != len(skill_rows): + die(f"counts 与行数不符: counts={counts} 实际 enemy={len(enemy_rows)} skill={len(skill_rows)}") + + skill_by_id = {} + for r in skill_rows: + if not isinstance(r, dict): + die(f"技能行非字典: {r!r}") + for k in SKILL_REQUIRED: + if k not in r: + die(f"技能行缺必需字段 {k}: {r!r}") + skill_by_id[str(r["skill_id"])] = r + + for r in enemy_rows: + if not isinstance(r, dict): + die(f"敌行非字典: {r!r}") + for k in ENEMY_REQUIRED: + if k not in r: + die(f"敌行缺必需字段 {k}: {r!r}") + + levels = {} + for r in enemy_rows: + levels.setdefault(int(r["level_index"]), []).append(r) + + out = ['', '', '', + '', '怪物图鉴', + f'', '', '', + '

怪物图鉴

', + '

本页由外置图鉴工具生成(tools/compendium_gen.py),数据来自 ' + 'sim-data/compendium/dump.json(game/data/tables/enemy.tres 与 skills.tres 经 ConfigDB ' + '单点读取导出)。只读对账面,非游戏内界面;重复生成直接覆盖。

', + f'

敌行 {len(enemy_rows)} 行 · 技行 ' + f'{len(skill_rows)} 行(counts 计数核对一致)

'] + + for lv in sorted(levels): + rows = levels[lv] + out.append(f'

{level_cn(lv)} level_index={lv}({len(rows)} 行)

') + bands = {} + for r in rows: + bands.setdefault(int(r["depth_band"]), []).append(r) + for band in sorted(bands): + out.append(f'

深度带 {band} depth_band={band}

') + for r in bands[band]: + out.append(render_enemy_card(r, skill_by_id)) + out.extend(['', '']) + return "\n".join(out) + + +def main() -> int: + ap = argparse.ArgumentParser(description="怪物图鉴渲染端:dump.json → 自包含 index.html") + ap.add_argument("--dump", default=str(DEFAULT_DUMP), help="采集端导出 JSON 路径") + ap.add_argument("--out", default=str(DEFAULT_OUT), help="输出 HTML 路径") + args = ap.parse_args() + dump_path, out_path = Path(args.dump), Path(args.out) + if not dump_path.is_file(): + die(f"dump.json 不存在: {dump_path}") + try: + dump = json.loads(dump_path.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError) as e: + die(f"dump.json 读取/解析失败: {e}") + html = build_html(dump) + out_path.parent.mkdir(parents=True, exist_ok=True) + out_path.write_text(html, encoding="utf-8") + n_enemy = len(dump["enemy_rows"]) + n_skill = len(dump["skill_rows"]) + print(f"[compendium_gen] 完成: 敌行 {n_enemy} · 技行 {n_skill} → {out_path}") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) From e380631eaad15e78982d8cae6ab560d35fb35b33 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 4 Nov 2026 01:57:59 +0800 Subject: [PATCH 18/19] =?UTF-8?q?=E5=86=99=E5=8D=A1(EffectPort=E8=93=84?= =?UTF-8?q?=E5=8A=9B=E5=B1=82=E5=88=A0=E9=94=AE=E6=89=B9=C2=B7v1.1):=20gri?= =?UTF-8?q?lling=E5=9B=9B=E8=A3=81=E7=82=B9=E8=90=BD=E7=A8=BF=E2=80=94?= =?UTF-8?q?=E2=80=94=E2=91=A0damage=5Fcontroller=E5=9B=9B=E5=A4=84?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E5=8F=AA=E6=B8=85charge=5Flayers=E5=85=B3?= =?UTF-8?q?=E8=81=94=E8=AF=AD=E4=B9=89=E5=8E=BB=E9=80=80=E5=BD=B9=E5=90=8D?= =?UTF-8?q?=E7=95=99=E6=9C=BA=E5=88=B6=E6=8F=8F=E8=BF=B0(=E4=BA=94?= =?UTF-8?q?=E6=8B=8D=E5=9D=97=E5=85=B6=E4=BD=99=E9=80=80=E5=BD=B9=E5=90=8D?= =?UTF-8?q?=E4=B8=8D=E5=8A=A8)=20=E2=91=A1=E6=94=B9=E5=86=99=E6=97=8F?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E5=AD=A4=E5=84=BF=E6=96=B0=E7=AB=8B=E5=BE=85?= =?UTF-8?q?=E5=8A=9E=E6=9D=A1=E7=9B=AE(spike/armor=5Frewrite/discount=5Fsh?= =?UTF-8?q?ift/trade=5F*=E9=9B=B6=E5=86=85=E5=AE=B9=E6=B3=A8=E5=86=8C,?= =?UTF-8?q?=E5=94=AF=E4=B8=80modify=5Fticket=E5=9C=A8=E5=BD=B9=E8=A1=8C=3D?= =?UTF-8?q?=E6=B7=AC=E6=AF=92=E5=88=83=E7=BA=B9clamp=5Fbonus;=E4=BA=94?= =?UTF-8?q?=E6=8B=8D=E6=B3=A8=E9=87=8A=E9=80=80=E5=BD=B9=E5=90=8D=E5=8F=99?= =?UTF-8?q?=E4=BA=8B=E5=B1=82;=E5=BE=85=E5=A4=84=E7=BD=AE=E6=96=B9?= =?UTF-8?q?=E5=90=91=E8=A3=81=E5=86=B3)=20=E2=91=A2req-card=E6=8A=80?= =?UTF-8?q?=E8=83=BD=E8=90=BD=E5=8D=A1=E7=89=87=E8=90=BD=E7=9B=98=E6=97=B6?= =?UTF-8?q?=E7=82=B9=E6=9D=A1=E6=AC=BE(=E8=B1=81=E5=85=8D=E9=9D=A2?= =?UTF-8?q?=E4=B8=BB=E5=8C=BA=E7=9B=B4=E6=94=B9,=E4=B8=8D=E5=85=A5?= =?UTF-8?q?=E6=9C=AC=E6=89=B9)=20=E2=91=A3=E7=BC=96=E6=8E=92=E6=84=8F?= =?UTF-8?q?=E5=90=91=E5=87=91=E6=89=B9;=20=E7=A8=8B=E5=BA=8F=E7=BA=A0?= =?UTF-8?q?=E9=94=99=E8=AE=B0=E5=BD=95=E5=9C=A8=E6=A1=88(v1.0=E6=88=90?= =?UTF-8?q?=E6=96=87=E6=9C=AA=E5=A4=8D=E6=A0=B8=E6=80=81=E8=A2=AB=E8=AF=AF?= =?UTF-8?q?=E6=94=B6=E5=8F=A3=E5=90=88=E5=9B=9E,=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E4=B8=8D=E6=B4=97);=20=E5=BE=85=E6=88=90=E7=AB=8B=E8=A3=81?= =?UTF-8?q?=E5=86=B3=E5=90=8E=E6=89=8D=E5=90=88=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../需求卡片-EffectPort蓄力层删键批-2026-11-04.md | 7 ++++--- 待办清单.md | 14 +++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md b/reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md index 4bf73382..5aacb09e 100644 --- a/reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md +++ b/reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md @@ -1,8 +1,8 @@ # 需求卡片:EffectPort 蓄力层删键批 > 来源:待办清单「EffectPort biz_fact 键 charge_layers——无属主数据游离出领域实体的处置」(2026-11-02 登记,来源=审计发现;需求性工程条目,证据指认在条目实况)。**唯一事实源:该条目实况所引证据链+本卡「现状事实」节代码级考证(2026-11-04 全部实查复核)。** -> 裁决沿革:删除方向 2026-11-02 用户裁(总判据「机制数据一律长在所属封装实体的内部属性(表行字段)里,全局常量与无主账本清零」);2026-11-04 本会话全仓考证确认死代码(零内容消费面)后用户发令删除。 -> 版本:v1.0(2026-11-04) +> 裁决沿革:删除方向 2026-11-02 用户裁(总判据「机制数据一律长在所属封装实体的内部属性(表行字段)里,全局常量与无主账本清零」);2026-11-04 本会话全仓考证确认死代码(零内容消费面)后用户发令删除;2026-11-04 grilling 复核四裁(注释口径甲=只清 charge_layers 关联语义/改写族孤儿另立待办/req-card 落盘时点条款落技能/编排意向凑批)。 +> 版本:v1.1(2026-11-04) ## 1. 目标与完成定义 @@ -67,6 +67,7 @@ - `test_charge_layers_consumed_same_round` 函数**不改名**——它是 swap_charge_layers(蓄力周转)测试,函数名属该计数器域;且 README:126 能力行代表用例名锚定此名,实现批禁写 README。 - 蓄力周转、敌方蓄力、RAP/转存率任何面(契约 1–3)。 - 蓄力周转测试面牵连核对结论:`refresh_feats_test` V8 组全部经效果引擎计数器域运行,不触 `action_economy.charge_layers`(全仓 grep 已证)——零牵连,无需同批改动。 +- **改写族内容孤儿机制**(grilling 2026-11-04 新发现,另立待办):damage_controller.gd 按序改写族通用机制的 spike/armor_rewrite/discount_shift/trade_* 子分支零内容注册(全仓唯一 modify_ticket 在役行=淬毒刃纹 clamp_bonus,feats.tres:854)+五拍注释退役名叙事层(矿工重锤/专注/猎弱本能)——不持数据键、非本卡对象,已立待办清单专条,处置方向归其自己的设计讨论。 **明示不收件的去向**:无——单链清退一次做完,无拆尾。 ## 6. 关联文档同步面 @@ -112,7 +113,7 @@ ### T1 注释清尾与零残留核验(≈0.25 工作日) -- [ ] `damage_controller.gd:271/338/352/433`:四处退役专长名注释删或改写为现状口径(禁残留整备军备/铁壁/厚积薄发/charge_layers 字样;:433 行剩余的 shield 订阅面注释主体保留,只删按层缩放句) +- [ ] `damage_controller.gd` 四处只清 charge_layers 关联语义、改机制语言,五拍块其余退役名(矿工重锤/专注/猎弱本能——grilling Q1 甲裁)不动::271 第三拍句删「when charge_layers≥3 在 dispatch 判定——满层持续状态口径」分句与「厚积薄发」点名,spike_ready 机制行为描述保留;:338 删「整备军备」点名,句改「attack_bonus per 计数器层值」机制口径;:352 删「厚积薄发」点名,改「modify_ticket mode=spike 满层口径」;:433 删「铁壁整备」点名,shield 订阅面机制描述保留(禁残留整备军备/铁壁/厚积薄发/charge_layers 字样) - [ ] `effect_port_test.gd:16/57/103`:三处误标注释改写——:16 改「蓄力周转计数器(feats.tres swap_charge_layers 行)」、:57/:103 删「整备军备/铁壁」字样改现状描述 - [ ] 零残留判据:`grep -rn "charge_layers\|charge_full\|CHARGE_LAYER\|蓄力层\|转蓄力\|厚积薄发\|铁壁\|整备军备" game/ --include="*.gd" --include="*.tres"` 除 `swap_charge_layers` 域(`refresh_feats_test.gd` 函数名 `test_charge_layers_consumed_same_round` 与 `feats.tres` swap 行)外零命中 - [ ] S13 核对:`action_economy.gd` 类变量数较登记值只降不升(删 `_charge_layers` 后预期 10→9);其余触面同判据 diff --git a/待办清单.md b/待办清单.md index ca80ebb9..98a0321c 100644 --- a/待办清单.md +++ b/待办清单.md @@ -273,12 +273,24 @@ #### EffectPort biz_fact 键 charge_layers——无属主数据游离出领域实体的处置(2026-11-02 登记,来源=审计发现) -**实况**:证据=reports/审计-全库架构审查-2026-10-29.md §3.1 B 类第 2 行+`game/core/effect_port.gd:4`(biz_fact 闭面五键)+`game/core/action_economy.gd:14/37/203`(裸账本与唯一写点)。2026-11-02 架构审查逐键核闭面:其余四键各有领域实体持有数据,唯 charge_layers 背后是无主账本(全仓零订阅注册、零表行消费);用户裁决=删除方向,总判据「机制数据一律长在所属封装实体的内部属性(表行字段)里,全局常量与无主账本清零」。需求卡片 reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md(v1.0——处置范围、残留面考证与断言换代申报全载卡内)。 +**实况**:证据=reports/审计-全库架构审查-2026-10-29.md §3.1 B 类第 2 行+`game/core/effect_port.gd:4`(biz_fact 闭面五键)+`game/core/action_economy.gd:14/37/203`(裸账本与唯一写点)。2026-11-02 架构审查逐键核闭面:其余四键各有领域实体持有数据,唯 charge_layers 背后是无主账本(全仓零订阅注册、零表行消费);用户裁决=删除方向,总判据「机制数据一律长在所属封装实体的内部属性(表行字段)里,全局常量与无主账本清零」。需求卡片 reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md(v1.1——处置范围、残留面 15 处考证、断言换代申报与 grilling 四裁点落稿全载卡内)。 + +**2026-11-04 grilling 四裁(实现面按推荐案)**:①注释只清 charge_layers 关联语义(四处去退役名留机制描述),五拍其余退役名不动;②改写族孤儿另立条目(见下);③req-card 落「卡片落盘时点」条款;④编排凑批。纠错记录:v1.0 曾成文未复核态被误收口合回(错误在案);v1.1 新 worktree 落笔、成立裁决后才合回。 **改动面**:游戏代码 **状态**:已写卡 +#### damage_controller 按序改写族——内容孤儿机制与退役名注释层(2026-11-04 登记,来源=会话提及) + +**实况**:damage_controller.gd 按序改写族通用机制(trade_hit/trade_atk 交换、armor_rewrite 免掷、spike 满层必中与倍乘、discount_shift 轻甲改善——注释叙事 :266-273、改写执行 :283-309、spike 倍乘 :350-353)现役内容面仅淬毒刃纹一行 modify_ticket(mode=clamp_bonus,feats.tres:854):其余子分支零表行注册(全仓 grep 证,含天赋树 tree_rules 面零 spike)——「框架先行、内容未接」同族债,与 charge_layers 同形态但不持数据键。五拍注释全部以旧 27 专长名叙事(矿工重锤/专注/厚积薄发/猎弱本能,道具退役素材库.md:43-47 退役在案);其中 charge_layers 关联四处已归 EffectPort 蓄力层删键批卡处理,其余退役名注释不在该卡范围。证据:reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md 范围边界节(2026-11-04 grilling 复核发现)。 + +**缺口**:还差处置方向裁决——删孤儿分支(零内容面随批清退)vs 留机制待内容(专长池扩充时接),裁后写卡;注释叙事层是否随处置批一并改机制语言同裁。 + +**改动面**:游戏代码 + +**状态**:待文档设计 + #### ci_watch 中间态误写终局红回执(2026-11-04 登记,来源=批次移交) **实况**:2026-11-04 run 37(commit 536dc072)实证——ci-status.json 于 16:59:55 写入 verdict=red(note=远端CI state=failure, run 37),而该 run 实际 17:03:10 才以「Job succeeded」落定,现查 Gitea API 组合状态=success、run conclusion=success;回执与真值相反,下游按「红未修不开新批」被误阻塞(验收档与条目限长批开工时人工查 API 解封)。证据=job 日志结尾「Job succeeded」(Gitea API actions/jobs/38/logs)+commits/536dc072/status 现查 success。修复方向=轮询只认 run conclusion 落定后的终局态(pending/中间态不写盘继续等)。 From a5db533ec785767d2c3d436fcce44228986db859 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 4 Nov 2026 02:24:15 +0800 Subject: [PATCH 19/19] =?UTF-8?q?=E4=BF=AE=E5=A4=8D(CI=E8=BF=BD=E7=BB=BF?= =?UTF-8?q?=C2=B7fix-docterm):=20=E5=BE=85=E5=8A=9E=E6=B8=85=E5=8D=95:288?= =?UTF-8?q?=E9=80=80=E5=BD=B9=E8=AF=8D=E3=80=8C=E9=9A=8F=E6=89=B9=E3=80=8D?= =?UTF-8?q?=E6=94=B9=E3=80=8C=E9=A1=BA=E5=B8=A6=E3=80=8D(2026-10-15?= =?UTF-8?q?=E9=80=80=E5=BD=B9=E4=BB=A3=E8=AF=8D,=E8=93=84=E5=8A=9B?= =?UTF-8?q?=E5=B1=82=E5=88=A0=E9=94=AE=E6=89=B9=E6=96=B0=E7=AB=8B=E6=9D=A1?= =?UTF-8?q?=E7=9B=AE=E7=BC=BA=E5=8F=A3=E5=8F=A5=E5=B8=A6=E5=85=A5);=20doc?= =?UTF-8?q?=5Fterm=20--strict=E9=80=80=E5=87=BA=E7=A0=810+pipeline=5Fgate?= =?UTF-8?q?=20PASS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 待办清单.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/待办清单.md b/待办清单.md index 98a0321c..c3f2e171 100644 --- a/待办清单.md +++ b/待办清单.md @@ -285,7 +285,7 @@ **实况**:damage_controller.gd 按序改写族通用机制(trade_hit/trade_atk 交换、armor_rewrite 免掷、spike 满层必中与倍乘、discount_shift 轻甲改善——注释叙事 :266-273、改写执行 :283-309、spike 倍乘 :350-353)现役内容面仅淬毒刃纹一行 modify_ticket(mode=clamp_bonus,feats.tres:854):其余子分支零表行注册(全仓 grep 证,含天赋树 tree_rules 面零 spike)——「框架先行、内容未接」同族债,与 charge_layers 同形态但不持数据键。五拍注释全部以旧 27 专长名叙事(矿工重锤/专注/厚积薄发/猎弱本能,道具退役素材库.md:43-47 退役在案);其中 charge_layers 关联四处已归 EffectPort 蓄力层删键批卡处理,其余退役名注释不在该卡范围。证据:reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md 范围边界节(2026-11-04 grilling 复核发现)。 -**缺口**:还差处置方向裁决——删孤儿分支(零内容面随批清退)vs 留机制待内容(专长池扩充时接),裁后写卡;注释叙事层是否随处置批一并改机制语言同裁。 +**缺口**:还差处置方向裁决——删孤儿分支(零内容面顺带清退)vs 留机制待内容(专长池扩充时接),裁后写卡;注释叙事层是否与处置批一并改机制语言同裁。 **改动面**:游戏代码