Merge branch 'master' into iter43
This commit is contained in:
commit
d7b8839fcf
38 files changed
+1328
-105
No files matched your search
@@ -2,8 +2,8 @@
|
||||
|
||||
## 文档状态
|
||||
|
||||
- 版本:1.24
|
||||
- 最近更新:2026-10-29(尾波清偿批设计闭合落文——「战斗编排域拆件定稿」节增补轴丙 BoardInstaller(`core/board_installer.gd`,实现批建件):装板域六函数迁出、宿主复位留薄壳、BoardGenerator 实例随件;battle_orchestrator 行 B1 域文件集句两新件→三新件随动;迭代 41 反哺注记转正文现状,沿革查 git)
|
||||
- 版本:1.25
|
||||
- 最近更新:2026-10-29(零豁免五键清偿设计闭合落文——S13 三条豁免登记注销〔main 组合根/battle_orchestrator 类变量/tune_sim 测量面〕;五案设计闭合、实现批建件:ui_registry 界面注册面、RoundCycle+BattleFacts、CellUnit 两绘制域件、StandeeBody 两状态件、tune_sim 信号步进状态机;gdstyle inner-class 计数截断缺陷登记;沿革查 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`,文档树构成以根索引为准)
|
||||
@@ -106,20 +106,23 @@
|
||||
| **reward_economy**(B4) | 格面资源身份映射(install 期预分配、Ready 只读、换图映射消亡)、极性路由字典面((类型, 极性)→ 字典行查询;路由执行归 B1 授予段)、F6 当量供给投影 | 封闭 API:roll_board / query_identity / query_full_snapshot / grant / grant_clear / retire_mapping / polarity_row / phase / weighted_pick;另有 is_mapped 静默布尔投影(批量工具用) | ConfigDB(RewardTable);BattleFxHost 经注入 Callable `luck_bias_query` 取偏运合计(reward_roll 发射与 bias_rewards 求和移至效果层完成);reward_roll 流(scope = 每次 install 批) | 无 |
|
||||
| **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 同签名委托承载(外部零变化) | ConfigDB(商店行集);注入 RngServiceCore;宿主钱包/账本引用;pool 模式令牌消耗与判定经注入 Callable 转 CurioDeck | 无 |
|
||||
| **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`);外部调用面 2026-10-29 D3 裁改直连(LevelRunner 同签名委托壳删除——并排卡「level_runner 商店委托层拆除」迭代 42 承接,调用方改址) | 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 纯逻辑) |
|
||||
| **AttuneLoadout**(`core/attune_loadout.gd`,同调配装件,已实装(2026-10-27 迭代 39 拆件批)) | 装备中的秘宝件对象集唯一所有者(每件内含充能单位与重置周期);同调充能的物化行为唯一事实源——种行/补行改写时同步(RunLedger 充能字典轨与差额对账函数退役);旧档 aux_items 同调行迁移归件 | 构造注入;充能查询/消耗/按周期重置原语;断点自交片段(attunement_charges 键,键名与策略不变) | ConfigDB(秘宝行集);TreasureItems(同调行投放面);注入战斗使用路径 | 无 |
|
||||
| **CurioStop**(`core/curio_stop.gd`,三选一停点件,已实装(2026-10-27 迭代 39 拆件批)) | 三选一停点编排唯一所有者(架构原则 9 本域承载):停点三态(关卡完成三选一在途/已兑付待推进/奖励节点三选一在途)、刷新三源账(刷新件 X/营地池 Y/刷新券存量/付费刷新计数)、兑付方法族(pick/refresh/redeem/skip)、凭证出箱(RAP/时沙待注入);三选一信号面自带;零自动推进停点语义承载 | 对外=开停点/刷新/兑付/放行谓词/交断点片段五组入口+信号面(curio_choice_presented/curio_resolved);由 AdventureRunner 关卡完成受理时调用 | ConfigDB;注入 CurioDeck(抽签/摘牌)与 HeroLedger(落账);随机只经 CurioDeck 的 reward_pick 封闭流 | 无 |
|
||||
| **breakpoint_store**(`core/breakpoint_store.gd`,冒险域·断点组装与回放件,2026-10-29 零豁免裁设计闭合——实现批建件) | 存档断点组装与回放唯一承载(自 adventure_runner 收编 6 成员+函数族):断点快照拼盘、回放回填、读侧策略分发;`BREAKPOINT_FIELDS` 27 键登记单源随件(键名/策略标签/键序冻结) | 构造=引用束注入;`resume_adventure` 留宿主薄壳;断点键面零变化 | adventure_runner(宿主);注入主角账三件与 curio/stop/bank/loadout 引用 | 无(RefCounted 纯逻辑) |
|
||||
|
||||
### 功能层
|
||||
|
||||
| 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API |
|
||||
|---|---|---|---|---|
|
||||
| **battle_orchestrator**(B1) | 段序骨架(七段结构冻结)、轮 facts 缓冲、可回放步骤流、[明细行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(基础行型+扩展行两层 + 字段分层,词表以 owner「明细流水」节为准)、条款③⑤闭合对账、**战斗域全部跨系统调用权**、效果引擎宿主面与树规则挂点施加面(**已拆出 BattleFxHost 并实装(2026-10-28 迭代 40——battle_fx_host.gd/reward_grant.gd 两件在库,效果引擎宿主面归 BattleFxHost 行承载,拆件细则见「战斗编排域拆件定稿」节)**) | `begin_battle(encounter)`;窗口/刷新意图提交面(扮演 D1);`level_clear()`;步骤流(输出契约) | B2/B3/B4 全调用面(**唯一调用方=B1 域文件集:battle_orchestrator.gd + settlement/ 五段段类 + damage_controller + 拆件后三新件**);A3 request_refresh 代理 + 回发;A2 install/retire + 三事件订阅;A1 generate(attempt 非 scope 事件);D2 SettlementTable + set_reload_gate | 无(零随机、禁 await——切片 88 冒烟实证可回放) |
|
||||
| **battle_orchestrator**(B1) | 段序骨架(七段结构冻结)、轮 facts 缓冲、可回放步骤流、[明细行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(基础行型+扩展行两层 + 字段分层,词表以 owner「明细流水」节为准)、条款③⑤闭合对账、**战斗域全部跨系统调用权**、效果引擎宿主面与树规则挂点施加面(**已拆出 BattleFxHost 并实装(2026-10-28 迭代 40——battle_fx_host.gd/reward_grant.gd 两件在库,效果引擎宿主面归 BattleFxHost 行承载,拆件细则见「战斗编排域拆件定稿」节);2026-10-29 零豁免裁设计闭合:RoundCycle/BattleFacts 两新件随批(宿主 38→15、S13 豁免第三条注销——见下两行与定稿节轴丁)**) | `begin_battle(encounter)`;窗口/刷新意图提交面(扮演 D1);`level_clear()`;步骤流(输出契约) | B2/B3/B4 全调用面(**唯一调用方=B1 域文件集:battle_orchestrator.gd + settlement/ 五段段类 + damage_controller + 拆件后三新件**);A3 request_refresh 代理 + 回发;A2 install/retire + 三事件订阅;A1 generate(attempt 非 scope 事件);D2 SettlementTable + set_reload_gate | 无(零随机、禁 await——切片 88 冒烟实证可回放) |
|
||||
| **BattleFxHost**(`core/battle_fx_host.gd`,B1 域·效果引擎宿主件,2026-10-26 编排域拆件设计定稿——实现批建件) | 效果引擎挂点施加面唯一承载(自 battle_orchestrator 收编 fx 族):事件发射与事实判定(_fx_emit/_fx_fact)、主角 AC 基线与本轮/本战 AC 累积、bonus_delta 四轴累积(战末宿主 drain 汇入账本)、揭示待兑队列与兑付(含 _fx_revealing 再入闸——同步信号回环防二次缓冲二次兑付)、树规则合成订阅的 round/battle 桶计数器持有(桶随编排器生灭语义不变) | 构造=引用束注入(防 _init max-parameters 新键);bind 时注入 emit Callable(行发射经宿主协议面单点)与兑付 Callable(RewardGrant 授予面——揭示队列 flush 回调);只读投影分两类消费方:AC 累积/bonus_delta 供宿主呈现快照与战末 drain,揭示态供宿主 A2 订阅旁路判定;`luck_bias_for(cell_count) -> int` 偏运合计查询口(体内三参形 dispatch——reward_roll 发射与 bias_rewards 求和自 RewardEconomy 收回本件,RewardEconomy 经注入 Callable 消费) | EffectEngine(EffectContext 引用束);RngServiceCore(fx_reveal 封闭流——除该流外零随机);A2 minesweeper(板读与 fx_reveal 调用);A3 action_economy(queue_ap_delta/charge_layers 读);B3 status_container 读;B2 unit_container 读(hp_ratio);DamageController(set_hero_ac_override);ConfigDB;encounter 引用 | 无(零 await——效果引擎全同步解释器) |
|
||||
| **RewardGrant**(`core/reward_grant.gd`,B1 域·奖励授予件,2026-10-26 编排域拆件设计定稿——实现批建件) | 奖励授予唯一兑付管线(自 battle_orchestrator 收编 grant 族):极性字典路由与封印溢价兑付(_grant_routed)、三种行应用(flat/percent/gp)、伤害单据提交面(_submit 族)、清图奖励与身份授予、秘宝使用编排(use_treasure 四步)、战斗域 GP 缓冲 escrow 与授予段暂存伤害闸(_defer_board_damage/_deferred_board) | use_treasure 编排入口(treasure_interact_controller 经组合根现值回调直连);授予入口(结算段类直调);只读投影(escrow 读与 GP 掉落合计——宿主呈现快照与 _roll_gp_drop 消费) | B4 RewardEconomy(polarity_row/grant);B1 域 DamageController(开单);BattleFxHost 引用(treasure_used 事件发射与计数器消耗);A2 minesweeper(校验回调/fx_reveal/remove_mines_in);A3 action_economy(相位闸/grant_ap/queue_ap_delta);B3 status_container(apply_effect/池读);B2 unit_container(hero_unit/heal);ConfigDB;注入 emit Callable、宿主 fatal Callable(battle_result 状态机唯一写点留宿主)、宿主 attune 读投影(_attune_safe_seen)、encounter 账本引用;TreasureItems 经宿主 setter 转发注入(库存注入时序在宿主构造之后) | 无(零随机零 await——授予期零随机口径,roll 值授予前已定) |
|
||||
| **damage_controller**(B1 域·伤害单据管线) | 伤害单据唯一兑现管线(单据九栏目声明→分量掷点/克制修正/伤害下限归一→明细行发射;双方同规) | 兑付入口(编排侧开单)+ fx 揭示回调注入位 | B2 单位实例(单据目标传入);B1 注入(EffectContext 引用束与编排回调) | 无 |
|
||||
| **BoardInstaller**(`core/board_installer.gd`,B1 域·装板域件,2026-10-29 尾波清偿批设计闭合——实现批建件,细则见「战斗编排域拆件定稿」节轴丙) | 棋盘安装与变异布置域唯一承载(自 battle_orchestrator 收编装板族六函数):生成受理、全局作用域变异决议、资源摇号资格域组装(roll_board 恰一次)、region 变异决议与连通片布置;BoardGenerator 实例随件自建自接线(宿主成员退役)——宿主侧装板后状态复位(封印/完美计数清零、板序推进、board_changed 发射、秘宝叠加层退役)留宿主薄壳,时序逐字保持 | `install(during_round) -> bool` 单入口;构造=引用束注入(rng/db/minesweeper/reward_economy/encounter 只读引用+宿主 fatal Callable——防 _init max-parameters 新键) | A1 board_generator(件内持有);A2 install_board;B4 roll_board/board_skew 写;A4 变异决议行集经 ConfigDB;board_gen/variant_place 两封闭流随件、流名与开流时点零漂移 | 无(零 await——装板全同步) |
|
||||
| **RoundCycle**(`core/round_cycle.gd`,B1 域·轮循环驱动件,2026-10-29 设计闭合——实现批建件) | 轮循环驱动域唯一承载(自宿主收编 7 成员):结算五段段件持有与驱动、重入门闸、开轮摇号、踩雷账 | 构造=引用束注入;段驱动入口由宿主接线调用 | B1 宿主;settlement/ 五段段类;A3 相位读 | 无 |
|
||||
| **BattleFacts**(`core/battle_facts.gd`,B1 域·战斗事实件,2026-10-29 设计闭合——实现批建件) | 战斗事实域唯一承载(自宿主收编 14 成员):受理事实(encounter)、轮 facts 缓冲(reveals/seals/path)、封印判定账、事实溯源、同调快照读面;attune 状态两成员随件(行为函数留宿主) | 构造=引用束注入;宿主与段类经注入引用读写 | B1 宿主;A2/A3 只读 | 无 |
|
||||
| **settlement/ 五段段类**(B1 域·结算段件) | B1 每轮结算序列的五段逻辑件(授予/增益减益/战斗/衰减/判定——细则见下「战斗域装配现状」节) | 段处理入口(B1 接线调用);可直接 `new()` 单测 | B2/B3/B4 兑付面与 B1 轮 facts 缓冲(各段按职责) | 无 |
|
||||
| **level_runner**(C1-lite,切片已建) | 关卡域生命周期(节点链推进、共享 B4 + HP 携带、关卡末 level_clear) | 节点推进接口;LevelTable(`level.tres`——节点 enum {battle,reward,rest,boss}、末节点必须 Boss、ConfigDB 跨表校验⑧) | B1(直构 BattleOrchestrator 接线战斗)、ConfigDB LevelTable | 无 |
|
||||
| **run_structure**(C2) | 冒险/关卡序列、失败重开、**master_seed 唯一接线方** | (契约规范源:`../../gdd/systems/冒险循环/冒险结构.md`) | RngService.set_master_seed、C3/D2 | 无 |
|
||||
@@ -134,10 +137,11 @@
|
||||
|
||||
- **轴甲两件**: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 存量债全量清偿」条目。
|
||||
- **轴丙一件(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 复核)。
|
||||
- **跨件单向接线**:RewardGrant 持 BattleFxHost 引用(treasure_used 事件发射与计数器消耗);BattleFxHost 对授予面走 bind 时注入的兑付 Callable(揭示队列 flush 回调)——禁双向强引用(两件均 RefCounted,环引用随每战新建泄漏)。行发射经 bind 时注入的 emit Callable(协议面单点留宿主——CurioDeck bind_handlers 同款先例,禁件回调宿主私有族);轮 facts 缓冲留宿主、fx 件经注入取值;_seal_consumed 留宿主(与 A2 seal_judged 订阅同域);fatal 经注入 Callable 转宿主 _fatal(battle_result 状态机唯一写点不变)。注入 Callable 亦属接线面、同单向纪律——禁为省参数改持对象引用。授予件对账本零强引用:战斗期消费经 `battle_hooks` 三键回调束(attune_consume/vision_add/negative_blast,bind_battle 缺键 assert),宿主侧三单点记账(2026-10-28 迭代 40 合并适配实装——RunLedger 类已随迭代 39 退役,直持对象引用无处可指)。
|
||||
- **战斗域读面(RunLedger 退役后)**:账本读经编排器 `_journal()`/`_attune_loadout()` 现值派生(GainJournal/AttuneLoadout,enc 派生、无成员接收);冒险桶经 `enc["adv_bucket"]` 下传 `battle_fx_host.mount_buckets`;战末 bonus 四轴经 `GainJournal.gain_bonus` 汇入(2026-10-27 迭代 39 主角账三件落地、迭代 40 合并适配承接)。
|
||||
- **settlement/ 段类随动**:段类构造注入直持宿主+两新件三引用(Middle Man 禁令封转发壳——调用点改指),授予段读写面点名:_grant_routed×5/_submit×6/escrow 写/_fx_new_resource_types/_feat_first_dig_used/_fx_bonus_delta 写/_apply_ac_bonus/_fx_enqueue_reveal/_flush_pending_reveals/_grant_clear_reward/counters_ctx;战斗段 _defer_board_damage 复位与 _deferred_board 结账改指 RewardGrant。四个授予段 helper(_feat_yield_adjust/_harmful_variants/_harmful_adjacent/_hits_of)与 _pool_effective/perfect_sweep_earned 留宿主(段类经宿主引用直调,现状形态)。
|
||||
- **attune 族原位保留**:同调配装 8 成员不进新件——迭代 39 副卡(AttuneLoadout 充能单源化)语义领地,两批零冲突;本波残留债归尾波。RewardGrant 经宿主 attune 读投影取 _attune_safe_seen。
|
||||
- **attune 族处置(2026-10-29 零豁免裁改判,原「原位保留」失效)**:attune 状态两成员归 BattleFacts、行为函数留宿主——迭代 39 副卡(AttuneLoadout 充能单源化)语义领地不破,外部三面消费点零改址;RewardGrant 经宿主 attune 读投影取 _attune_safe_seen 形态不变。
|
||||
- **呈现零变化**:两快照出口签名与载荷逐字不变,内部改读两件只读投影(快照本体不读揭示态——揭示态投影消费方=宿主 A2 订阅旁路判定);treasure_interact_controller 三触点分家——use_treasure 经组合根现值回调改注 RewardGrant(每战新建编排器,禁一次性直引防悬挂),minesweeper 读与 attune_convert_state 仍走宿主取值回调(双取值面);nest_preview_count 直读面零变化。
|
||||
- **S13 键账收敛义务**:12 个超标键随函数迁入新文件=基线外 NEW(use_treasure 长度/分支/局部/返回×4、_grant_routed 参数 8、_dispatch_row 参数 6、_apply_percent_row 参数 6、_apply_gp_row 参数 6、_apply_flat_row 参数 7+返回 9、_submit_flat_hero 参数 7、_fx_fact 返回 7)——卡内同步收敛为本波义务(_grant_routed 等签名随引用束注入改形、use_treasure 体拆分),禁波 0 合并 refresh 吸收新文件未还键;新件 _init 引用束注入防 max-parameters 新键。
|
||||
- **验收红线**:游戏行为零变化(RNG 消费序零漂移——fx_reveal 封闭流随件迁移取号序不变、信号顺序契约冻结、明细行协议词表零触碰、同种子逐位一致);battle_orchestrator 头注发射点指址随拆件改写(词表不动,指址须真);行数恶化债清偿义务(迭代 38 特批带红合并挂账 c4c69701——本波还债归绿);PARITY 触面(battle_orchestrator.gd 被改)实跑对拍须经用户批准、不得借机重锚;S13 改善非清零口径(宿主残留 8–10 键+随迁键卡内收敛后新件零残留为达标线)。
|
||||
@@ -149,7 +153,7 @@
|
||||
- **CurioDeck 转纯池**:bind_handlers 反向回调退役;商店购买消费经注入 Callable 链至 CurioStop 兑付单点——牌库只管抽签/消耗/cap 判定/凭证计数。
|
||||
- **RunLedger 退役**:四账各归其主——加算区/购买记录/钥石增量/特性集/真视记录归 HeroLedger,充能归 AttuneLoadout,冒险桶字典归应用层持有;战斗侧 encounter 注入面由单一账类引用改为多路(桶字典+实体账+配装件);ShopSession 账本引用面同步换代,商店属性商品加算改经 HeroLedger 单写原语。
|
||||
- **level_runner**:依赖改构造注入一次给齐(后置 setter 群与商店重绑机制退役;注入活引用禁快照——特性集共享引用语义保留);商店白盒转发属性撤除;战斗→关卡信号转发族保留(战斗实例每节点新建,关卡层做战斗域稳定面)。
|
||||
- **断点片段化**:各件自写自读自己的键(关卡层交关卡域五键片段:node_id/visited_ids/aux_items/shop_shelf/shop_visit_buys),缺键回退策略随领域知识归各件;应用层唯一落盘口(收齐各件片段拼成顶层快照后写盘),写触发点不变(五处);既有 27 键逐键冻结;新增获得日记键沿扩列不升版先例——旧档缺日记回退汇总键直载并跳过比对,日记在档时由日记推导汇总、与留存值不符即报错中止(迁移正确性自检)。
|
||||
- **断点片段化**:各件自写自读自己的键(关卡层交关卡域五键片段: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。
|
||||
- **调用直连**:不留中间人委托壳(纯转传=Middle Man 反模式,2026-10-26 用户裁定);呈现控制器经取值回调持件——回调只许捕获长活根对象,禁件方法 Callable(防悬挂);约 30 个调用文件改址;测试/探针直连件读写。
|
||||
- **验收红线**:游戏行为零变化(RNG 流名 reward_pick 与消费序零漂移、信号顺序契约冻结、同种子逐位一致);gdstyle 基线禁改(类变量计数下降属改善);怪物寻址 resolve_enemy_rowset 调用面与关卡参数档装配零变化(未来关卡主题的数据缝不堵)。
|
||||
@@ -160,6 +164,10 @@
|
||||
|---|---|---|---|---|
|
||||
| **D1 HUD**(呈现面拆分持续换代:组合根 main.gd + 三屏壳(MenuScreen/CampScreen/AdventureScreen)+ views/ 视图单元(现行承载面见「呈现层装配与会话生命周期」节;早期 9 单元清单与 LevelStripView 已随场景换代退役);营地覆盖层=四柜台并排〔树淬炼主界面/锻造工坊·秘宝匣钥匙门/图鉴常开——迭代 21 T6 程序占位重排〕) | 全部 Control/CanvasLayer(例外:BoardView 棋盘本体与 BattleStageView 站桩本体 = Control 壳 + SubViewportContainer + SubViewport + Node2D 世界〔BoardWorld/CellUnit;StageWorld/StandeeBody——B 区 slot_row 伴随件留壳层〕,探针契约面不变——棋盘 Node2D 迁移批 Phase A 2026-09-23 / 战斗舞台 Phase B 2026-09-26)、输入→意图翻译(**唯一提交路径 = settle_batch,不直调 A3**)、呈现义务状态记录(A2×6 / B2×4 / B3×4 / B4×5 / B1×3) | 视图单元接口(信号外发、setter 只读注入) | A2 compute_move_path / ActionOutcome;A3 ap/rap;B1 步骤流行协议(数据源);ConfigDB display_name | **MEDIUM**:Control / CanvasLayer / draw_* / InputEvent / RichTextLabel——对照 breaking-changes.md 4.5–4.7 条目(CanvasItem 线条无抗锯齿羽化、设备 ID 常量、RichTextLabel 图片参数两轮变化) |
|
||||
| **组合根拆件**(呈现侧写口子件:curio_interact_controller / camp_shop_presenter / treasure_interact_controller) | 代组合根执行核心写调用(冒险节点后续推进/营地购买与刷新/道具使用——依赖与回调由 main 构造注入) | 各拆件的写入口(仅组合根装配面可达;视图零直连) | 构造注入的核心写引用(推进/商店/道具各域——详见各拆件头注) | 无 |
|
||||
| **ui_registry**(`presentation/ui_registry.gd`,界面注册面,2026-10-29 零豁免裁设计闭合——实现批建件) | 呈现层接口面唯一承载:层序合同(LAYER_CONTRACT)迁驻与合同寻址、三域句柄容器 ui_screens(9 屏壳与覆盖层句柄)/ui_battle(5 战区句柄)/ui_modals(13 模态句柄+ModalFlow);组合根经其一级寻址接线,探针挂载假设迁移为 `main.ui.<域容器>.<句柄>`;七个探针别名/转发成员随批消灭 | 三容器属性+合同寻址口(RefCounted 门面,不挂树、零会话期引用) | 构造注入:三屏壳、覆盖层、战区句柄、ModalFlow(main_ui_build 交付随之改型) | 无(RefCounted) |
|
||||
| **board_hover**(`views/board_hover.gd`,悬停预承诺呈现域件,尾波清偿批 D2 设计闭合——实现批建件) | 悬停反馈域唯一承载(自 board_view 收编 11 函数族+_hover/_last_click 两成员):三语义光标、目标格边框、BFS 路径预览、chord 双击首遇锚;_r0 出生展开区成员留宿主 | 构造=引用束注入(cells/minesweeper/diggable 引用+光标写入与 hover_forbidden 注入回调);三入站口留宿主委托;hover_probe 读面留宿主 | board_view(宿主);输入事件经宿主入站口 | 无(RefCounted) |
|
||||
| **cell_base_layer/cell_mark_overlay**(`views/`,单格两绘制域件,2026-10-29 设计闭合——实现批建件) | 单格绘制域拆分(自 board_cell_unit 状态件 `_CellPaintState` 收编,入参与该层绘制命令同件):基座层(底面/描边/立面/投影/接触带/倒角,12 成员)与标识叠加层(标记/字形/徽章/封印/点迹/高亮/退色,13 成员);宿主 _draw 退为六步时序器,类变量 30→10 | 构造注入;绘制命令由宿主 _draw 按层序调用 | board_cell_unit(宿主);gdstyle 键各文件独立计数(12/13 均 ≤15) | 无(RefCounted) |
|
||||
| **standee_vitals/standee_motion**(`views/`,站桩两状态件,2026-10-29 设计闭合——实现批建件) | 站桩状态域拆分(自 `_StandeeState` 真实 25 成员收编):身份命值(hp/atk/状态值族,12 成员)与资产演出(动作/姿态/位移演出族,11 成员);三个演出探针计数器留宿主,宿主类变量 19→10 | 构造注入;st(沿用)/mo 两实例由宿主持有 | standee_body(宿主);battle_stage_view 写入面逐字保持 | 无(RefCounted) |
|
||||
| **HudPresenter**(`presentation/hud_presenter.gd`,迭代 37 加注) | 战斗屏**数据投影+文案拼装静态族**——核心状态→呈现文案的全部翻译集中于此(B/C/D 区文案与投影),静态无状态 | `refresh(…)` 全量重查装配(组合根每次动作/结算返回后调用,漏调即陈旧呈现)+只读静态投影族 | 核心读取只走 `settlement.presentation_snapshot()` 成文快照面(禁链式穿透结算内部);ConfigDB display_name | 无(RefCounted 静态) |
|
||||
| **board_resolvers**(`presentation/board_resolvers.gd`,迭代 37 拆出) | 棋盘每格渲染数据的只读解析回调四函数(奖励徽章身份——挖掘期 Active 相位内、地形变异数字遮蔽与角标、调试加成生效值)——有态绑定件,与无态静态投影族 HudPresenter 职责互斥 | 构造注入 db、调试浮窗与结算活态取值,产出绑定 Callable 供组合根接线 | ConfigDB / DebugOverlay / 结算活态取值 Callable | 无(纯投影) |
|
||||
| **main_ui_build**(`presentation/main_ui_build.gd`,迭代 37 拆出) | `_build_ui` 八步拆分件——组合根 UI 装配分步承接(三屏壳实例化、视图句柄接线、覆盖层装配与模态编排注入按步拆开);main 侧留同名薄委托,装配序与 z 序零改动 | 分步静态函数(成员访问经 root 显式传入) | 层序逻辑不在此件——唯一事实源仍是 `main.LAYER_CONTRACT` + `_apply_layer_contract()` | 同 D1(Control 装配面) |
|
||||
@@ -182,7 +190,7 @@
|
||||
### 三屏壳与组合根句柄面
|
||||
|
||||
- 呈现场景拆为三屏壳:MenuScreen(开始菜单屏)/CampScreen(营地屏)/AdventureScreen(冒险屏——内含关卡地图与战斗两容器)。
|
||||
- 屏成员经组合根 main.gd 一级句柄暴露(探针挂载假设 `main.X` 路径零迁移;**S13 豁免登记 2026-10-27:组合根类变量面即探针契约面——约 46 个句柄成员被探针挂载假设钉死,max-class-variables 对本件按架构契约豁免(键永久基线内、禁再恶化),豁免理由在册本节,禁为清键改写探针挂载契约**);局态一律住 RunScope 节点,禁在屏/视图侧持有局态引用。
|
||||
- 屏成员寻址自实现批起迁经界面注册面(**2026-10-29 零豁免裁+注册面设计闭合——实现批建件**):探针挂载假设 `main.X` 迁移为 `main.ui.<域容器>.<句柄>`(ui_screens/ui_battle/ui_modals 三域容器,约 867 处探针与系统测试引用随批改址);原 S13 豁免登记〔2026-10-27「组合根类变量面即探针契约面」〕注销;main.gd 类变量 49→15,注册面形态见「模块归属·呈现层」表 ui_registry 行;局态一律住 RunScope 节点,禁在屏/视图侧持有局态引用。
|
||||
- **组合根拆件**=组合根构造注入、代组合根执行核心写调用的呈现侧子件(现行三件:curio_interact_controller/camp_shop_presenter/treasure_interact_controller——冒险节点后续推进、营地购买与刷新、道具使用)。视图禁直连拆件;核心写调用的可达路径仍是「视图→信号→组合根(含拆件)→核心」,依赖规则与组合根单点装配不变。成员见「模块归属·呈现层」表。
|
||||
|
||||
### 视觉层装配合同
|
||||
@@ -310,9 +318,11 @@
|
||||
|
||||
本节为测试域(测试载体、判定口径、静态扫描域)的事实源。新增违规案例仍须先补 static_scan 规则再修码(code-conventions 缺陷-规范对照表纪律)。
|
||||
|
||||
**S13 测量面豁免登记(2026-10-27)**:`game/presentation/tune_sim_controller.gd` 的循环内 `await`(测速循环逐帧让出)是调参测量的 wall-clock 步进承载语义——重构即测量口径漂移,违行为零变化红线。该键按架构豁免(键永久基线内),豁免理由在册本段;同件 `print` 残留不豁免(信息已由 toast/JSONL 承载,随全清批删除)。
|
||||
**S13 测量面豁免注销(2026-10-29 零豁免裁)**:原循环内 `await` 豁免〔2026-10-27〕注销——tune_sim_controller 改 process_frame 信号常驻连接+步进状态机(每帧一局、帧相位逐点对齐,设计闭合、实现批建件);随批申报行为改动一处:运行态收尾由「每局置假」还原为「整批收尾单次置假」(消除与 wd8/ui_tune_probe 断言面的静态矛盾)。
|
||||
|
||||
**S13 豁免登记第三条(2026-10-28 迭代 40 卡①)**:`game/core/battle_orchestrator.gd` 的 max-class-variables 键——宿主保留面为「战斗编排域拆件定稿」节第 1 款锁定的职责承载面(状态机与生命周期、账本读面、attune 族原位、行发射基建、呈现投影),类变量阈值 15 在保留面锁定下不可达,按全清口径第二支臂登记架构豁免(键永久基线内、禁再恶化;实测键账 50→38)。
|
||||
**S13 豁免第三条注销(2026-10-29 零豁免裁)**:原 battle_orchestrator max-class-variables 豁免〔2026-10-28 迭代 40 卡①〕注销——RoundCycle/BattleFacts 两新件设计闭合(宿主 38→15,实现批建件,见「战斗编排域拆件定稿」节轴丁)。
|
||||
|
||||
**gdstyle 计数截断缺陷登记(2026-10-29 两设计批独立实证)**:gdstyle v0.4.0 对文件内 inner class 的成员计数存在截断——内嵌类中带行尾注释的属性声明截断其后续成员计数(standee_body 实测 31 声明仅记 19、board_cell_unit 33 仅记 30)。基线登记值属欠估;闸机扫描与基线同源、判定口径自洽不误报,债的真值以实查为准——零豁免各批按真实口径设计(实数低于阈值,不依赖解析缺陷)。登记待办:向 gdstyle 上游报 issue。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
## VERTICAL SLICE - NOT FOR PRODUCTION
|
||||
## 数值表单点访问入口:全部 .tres 表的加载、校验诊断与门面(垂直切片验证:改表即改玩法,数值零硬编码)。
|
||||
## 玩法代码禁止绕过本单点自建 load();行查询归各表类(表管自己的行——2026-10-27 全清设计定稿),
|
||||
## 玩法代码禁止绕过本单点自建 load();行查询归各表类(表管自己的行),
|
||||
## 表持有按域收进三容器(combat 战斗编排域/run 冒险 runner 域/crossrun 跨局元进度域),
|
||||
## 消费面经 db.<容器>.<表> 直连。「经 ConfigDB 单点读取」=经其持有的容器与表对象(架构 :88)。
|
||||
## headless --script 模式无 autoload——冒烟脚本显式实例化本类;加载失败 is_ready=false 加 fatal 封印,调用方须查。
|
||||
## 冒烟脚本可显式实例化本类(headless --script 亦会加载 autoload——共享 .tres 上的 resolver 归最后装载的实例);
|
||||
## 加载失败 is_ready=false 加 fatal 封印,调用方须查。
|
||||
class_name ConfigDb
|
||||
extends Node
|
||||
|
||||
const SCHEMA_VERSION := 1
|
||||
|
||||
const TABLE_MANIFEST := {
|
||||
"action_economy": "action_economy.tres",
|
||||
"variation": "variation.tres",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## 战斗域容器(D2 域容器——config_db 表持有按域收敛,2026-10-27 全清设计定稿):战斗编排域七表类型化持有。
|
||||
## 战斗域容器(D2 域容器——config_db 表持有按域收敛):战斗编排域七表类型化持有。
|
||||
## 零方法零行为——纯持有结构;「经 ConfigDB 单点读取」=经其持有的容器与表对象(架构 :88 定稿注记)。
|
||||
class_name ConfigDomainCombat
|
||||
extends Resource
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## 跨局域容器(D2 域容器——config_db 表持有按域收敛,2026-10-27 全清设计定稿):跨局元进度域五表类型化持有
|
||||
## 跨局域容器(D2 域容器——config_db 表持有按域收敛):跨局元进度域五表类型化持有
|
||||
## (跨局循环=单局之外的长线进度域)。零方法零行为——纯持有结构;
|
||||
## 「经 ConfigDB 单点读取」=经其持有的容器与表对象(架构 :88 定稿注记)。
|
||||
class_name ConfigDomainCrossrun
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## 冒险域容器(D2 域容器——config_db 表持有按域收敛,2026-10-27 全清设计定稿):冒险 runner 域七表类型化持有。
|
||||
## 冒险域容器(D2 域容器——config_db 表持有按域收敛):冒险 runner 域七表类型化持有。
|
||||
## 零方法零行为——纯持有结构;「经 ConfigDB 单点读取」=经其持有的容器与表对象(架构 :88 定稿注记)。
|
||||
class_name ConfigDomainRun
|
||||
extends Resource
|
||||
|
||||
@@ -187,8 +187,8 @@ func _vo_edges(nodes: Array, by_id: Dictionary, indeg: Dictionary, errs: Array)
|
||||
|
||||
## 阶段三·流事实域:入口集(入度 0)/终点集(无出边)与 Boss 终点判据、去路数形态
|
||||
func _vo_flow_facts(nodes: Array, indeg: Dictionary, errs: Array) -> Dictionary:
|
||||
var entries := []
|
||||
var terminals := []
|
||||
var entries: Array[int] = []
|
||||
var terminals: Array[int] = []
|
||||
for n in nodes:
|
||||
var id0: int = int(n["id"])
|
||||
var outs = n["next"]
|
||||
@@ -277,8 +277,8 @@ func _vo_width_rules(nodes: Array, errs: Array) -> void:
|
||||
|
||||
## 计数规则③·参数档对照:战斗保底/入口数/终点数/层高(params 为空时跳过)
|
||||
func _vo_params_check(params: Dictionary, nodes: Array, by_id: Dictionary, flow_ends: Array, errs: Array) -> void:
|
||||
var entries: Array = flow_ends[0]
|
||||
var terminals: Array = flow_ends[1]
|
||||
var entries: Array[int] = flow_ends[0]
|
||||
var terminals: Array[int] = flow_ends[1]
|
||||
var battles := 0
|
||||
for n in nodes:
|
||||
if String(n["type"]) == "battle":
|
||||
@@ -309,7 +309,7 @@ func _build(rg: RandomNumberGenerator) -> Dictionary:
|
||||
var entries: Array[int] = []
|
||||
for i in range(en):
|
||||
entries.append(_mk("battle", 0))
|
||||
var prevs: Array = _build_trunk(t, entries.duplicate())
|
||||
var prevs: Array[int] = _build_trunk(t, entries.duplicate())
|
||||
|
||||
var terminals: Array[int] = []
|
||||
for r in range(e):
|
||||
@@ -326,7 +326,7 @@ func _build(rg: RandomNumberGenerator) -> Dictionary:
|
||||
|
||||
|
||||
## 主链段(深度 1..t 逐层单链,主链段零 RNG):返回链末节点集(e>1 时收束为一处即归属大岔口)
|
||||
func _build_trunk(t: int, prevs: Array) -> Array:
|
||||
func _build_trunk(t: int, prevs: Array[int]) -> Array[int]:
|
||||
for d in range(1, t + 1):
|
||||
var nid := _mk("battle", d)
|
||||
for p in prevs:
|
||||
|
||||
@@ -52,7 +52,7 @@ const TIER_QUOTAS := {"common": 70, "excellent": 25, "rare": 7, "legendary": 0}
|
||||
@export var cap_segment: AdventureCapSegment = AdventureCapSegment.new() # 已拿上限段(curio_cap_* 9)
|
||||
|
||||
# —— 专长获取专长凭证(非 Boss 渠道的专长入口形态,奇物.md v2.7 渠道轴定位;
|
||||
# 四口径契约④:拿到即开不可囤积/罕见只在概率不在价格/一局限购一次/计步保底连续 5 展示未出
|
||||
# 四口径契约④:拿到即开不可囤积/稀有只在概率不在价格/一局限购一次/计步保底连续 5 展示未出
|
||||
# 第 6 必出(计数=展示次数、刷新重展计入、节点与商店共享、触发清零、限购满不再触发)。
|
||||
# 四参数全部 provisional 归曲线调参;limit/pity_step 系口径定死值,调参可复议)——
|
||||
@export var feat_ticket_chance: int = 20 # [0,100] knob(provisional)——每次非 Boss 渠道展示专长凭证出现概率 %
|
||||
|
||||
@@ -7,9 +7,9 @@ extends RefCounted
|
||||
## 三束按域收拢(u21——同 u20 形;views=视图句柄/getters=查询 Callable 活引用/flow=编排 Callable):
|
||||
## 原 12 参长签名收 4 参——字段即原构造参数逐一同名迁移,键面=消费方改址合同。
|
||||
var db
|
||||
var views: Dictionary = {} # {camp_overlay, shop_overlay, toast, start_overlay, logger}
|
||||
var getters: Dictionary = {} # {meta_get, save_get, runner_get}
|
||||
var flow: Dictionary = {} # {open_modal, close_modal, refresh_presentations}
|
||||
var views: Dictionary = {} # {camp_overlay, shop_overlay, toast, start_overlay, logger} # type-hint: ignore(三束异构混载——视图句柄/查询 Callable/编排 Callable)
|
||||
var getters: Dictionary = {} # {meta_get, save_get, runner_get} # type-hint: ignore(同上——Callable 束)
|
||||
var flow: Dictionary = {} # {open_modal, close_modal, refresh_presentations} # type-hint: ignore(同上——Callable 束)
|
||||
|
||||
|
||||
func _init(db_ref, views_bundle: Dictionary, getters_bundle: Dictionary, flow_bundle: Dictionary) -> void:
|
||||
|
||||
@@ -7,9 +7,9 @@ extends RefCounted
|
||||
## 三束按域收拢(u20——views=视图句柄/getters=查询 Callable 活引用〔禁快照〕/flow=编排 Callable):
|
||||
## 原 16 参长签名收 4 参——字段即原构造参数逐一同名迁移,键面=消费方改址合同。
|
||||
var db
|
||||
var views: Dictionary = {} # {curio_overlay, end_overlay, board_view, toast}
|
||||
var getters: Dictionary = {} # {meta_get, save_get, adventure_get, runner_get, adventure_mode_get}
|
||||
var flow: Dictionary = {} # {open_modal, open_modal_after_playback, close_modal, refresh_presentations, fatal_screen, gp_summary}
|
||||
var views: Dictionary = {} # {curio_overlay, end_overlay, board_view, toast} # type-hint: ignore(三束异构混载——视图句柄/查询 Callable/编排 Callable)
|
||||
var getters: Dictionary = {} # {meta_get, save_get, adventure_get, runner_get, adventure_mode_get} # type-hint: ignore(同上——Callable 束)
|
||||
var flow: Dictionary = {} # {open_modal, open_modal_after_playback, close_modal, refresh_presentations, fatal_screen, gp_summary} # type-hint: ignore(同上——Callable 束)
|
||||
|
||||
|
||||
func _init(db_ref, views_bundle: Dictionary, getters_bundle: Dictionary, flow_bundle: Dictionary) -> void:
|
||||
|
||||
@@ -78,7 +78,7 @@ func on_presented(payload: Dictionary) -> void:
|
||||
return
|
||||
ctx.views.end_overlay.open_victory(Narrator.battle_end_text("victory", false), "继续",
|
||||
ctx.views.board_view.get_global_rect(),
|
||||
"%s\n%s" % [String(ctx.flow.gp_summary.call()), Narrator.bonus_keystone_line(payload)])
|
||||
{"gp_summary": "%s\n%s" % [String(ctx.flow.gp_summary.call()), Narrator.bonus_keystone_line(payload)]})
|
||||
ctx.flow.open_modal_after_playback.call(ctx.views.end_overlay)
|
||||
ctx.flow.refresh_presentations.call()
|
||||
|
||||
|
||||
@@ -196,11 +196,11 @@ static func outcome_text(outcome: Dictionary) -> String:
|
||||
## 统计束收拢(u19——stats 六键 {wins, dmg_all, hp_left_win, hp_boss, rounds_all, death_nodes})
|
||||
static func tune_sim_report(n: int, atk_pct: int, hp_pct: int, stats: Dictionary, base_hp: int) -> String:
|
||||
var wins: int = stats.get("wins", 0)
|
||||
var dmg_all: Array = stats.get("dmg_all", [])
|
||||
var hp_left_win: Array = stats.get("hp_left_win", [])
|
||||
var hp_boss: Array = stats.get("hp_boss", [])
|
||||
var rounds_all: Array = stats.get("rounds_all", [])
|
||||
var death_nodes: Dictionary = stats.get("death_nodes", {})
|
||||
var dmg_all: Array = stats.get("dmg_all", []) # type-hint: ignore(stats 束 Variant 出值——元素类型归模拟域写入面,未参数化)
|
||||
var hp_left_win: Array = stats.get("hp_left_win", []) # type-hint: ignore(同上)
|
||||
var hp_boss: Array = stats.get("hp_boss", []) # type-hint: ignore(同上)
|
||||
var rounds_all: Array = stats.get("rounds_all", []) # type-hint: ignore(同上)
|
||||
var death_nodes: Dictionary = stats.get("death_nodes", {}) # type-hint: ignore(同上——键为败北节点标签)
|
||||
var lines: Array[String] = []
|
||||
lines.append("[b]模拟 N=%d(atk+%d%% / hp+%d%%)[/b]" % [n, atk_pct, hp_pct])
|
||||
lines.append("关卡完成率 [color=#%s]%.0f%%[/color](%d/%d)" % [UiKit.HEX_LOG_WIN, 100.0 * float(wins) / float(maxi(1, n)), wins, n])
|
||||
|
||||
@@ -50,10 +50,12 @@ func run(n: int) -> void:
|
||||
await panel.get_tree().process_frame
|
||||
logger.close_session()
|
||||
panel.set_sim_report(HudPresenter.tune_sim_report(n, panel.atk_pct(), panel.hp_pct(), stats, _base_hp))
|
||||
panel.set_sim_running(false)
|
||||
_running = false
|
||||
|
||||
|
||||
## 单局模拟域(循环体提函数——结果四桶记账;u19 stats 六键同构承载)
|
||||
func _run_one_level(autoplay, stats: Dictionary, i: int, panel, logger) -> void:
|
||||
func _run_one_level(autoplay, stats: Dictionary, i: int, panel, logger) -> void: # type-hint: ignore(驱动/面板/日志件鸭子型注入——同 run 构造缝)
|
||||
var st = autoplay.run_level(db, SEED_BASE + i, 1, panel.atk_pct(), panel.hp_pct(), false, logger)
|
||||
(stats["dmg_all"] as Array).append(st.hero_dmg)
|
||||
(stats["rounds_all"] as Array).append(st.rounds)
|
||||
@@ -64,5 +66,3 @@ func _run_one_level(autoplay, stats: Dictionary, i: int, panel, logger) -> void:
|
||||
elif st.result == "defeat":
|
||||
var key := "%d.%s" % [st.defeat_node_index, st.defeat_node_type]
|
||||
stats["death_nodes"][key] = int(stats["death_nodes"].get(key, 0)) + 1
|
||||
panel.set_sim_running(false)
|
||||
_running = false
|
||||
@@ -75,7 +75,7 @@ func _build_world_stage() -> void:
|
||||
|
||||
|
||||
## Control 文本半区域(round_label / stage_center / log_view 原样保留——C1 永久 Control)
|
||||
func _build_text_half(db_ref) -> void:
|
||||
func _build_text_half(db_ref) -> void: # type-hint: ignore(db 鸭子型注入——单测以最小 stub 构造)
|
||||
var vb := VBoxContainer.new()
|
||||
vb.add_theme_constant_override("separation", 4)
|
||||
vb.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
@@ -124,7 +124,7 @@ func _build_center_row(vb: VBoxContainer) -> void:
|
||||
|
||||
|
||||
## 壳层伴随件层域(最顶——世界站桩之上的 Control 触达面)+主角站桩注册(世界)+ 状态行伴随件(壳层)
|
||||
func _build_companion_layer(db_ref) -> void:
|
||||
func _build_companion_layer(db_ref) -> void: # type-hint: ignore(db 鸭子型注入——单测以最小 stub 构造)
|
||||
_companion_layer = Control.new()
|
||||
_companion_layer.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
_companion_layer.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
|
||||
@@ -198,7 +198,8 @@ func _draw_glyph_layer(rect: Rect2) -> void:
|
||||
draw_texture_rect(st.tex_mutation, rect, false)
|
||||
# ③ 数字/徽章(数字 ≥ 格高 50% 墨族对格底 ≥4.5:1;徽章右下角金,遮蔽态 = "?")
|
||||
if glyph != "":
|
||||
_draw_digit_plate()
|
||||
if plate:
|
||||
_draw_digit_plate()
|
||||
if st.tex_glyph != null:
|
||||
draw_texture_rect(st.tex_glyph, rect, false)
|
||||
else:
|
||||
|
||||
@@ -478,9 +478,9 @@ func _room_color(node: Dictionary, ctx: Dictionary) -> Color:
|
||||
## 选路停点(候选非空)非候选通道降透明——金岔路从结构网分离(干线共线重叠缺陷的
|
||||
## 视觉主因:不同源通道共用同一垂直干线,金边与石色边焊接成「整列可走」假象)
|
||||
func _draw_passage_layer(canvas: Control, ctx: Dictionary) -> void:
|
||||
var nodes: Array = ctx["nodes"]
|
||||
var pos: Dictionary = ctx["pos"]
|
||||
var cand_ids: Array = ctx["cand_ids"]
|
||||
var nodes: Array = ctx["nodes"] # type-hint: ignore(ctx 束 Variant 出值——布局缓存数组未参数化)
|
||||
var pos: Dictionary = ctx["pos"] # type-hint: ignore(同上——节点 id → 坐标)
|
||||
var cand_ids: Array = ctx["cand_ids"] # type-hint: ignore(同上——候选 id 集)
|
||||
var dim_passages: bool = not cand_ids.is_empty()
|
||||
for node in nodes:
|
||||
var from: Vector2 = pos[node]
|
||||
@@ -496,7 +496,7 @@ func _draw_passage_layer(canvas: Control, ctx: Dictionary) -> void:
|
||||
|
||||
## 房间方块域:底色随行进态+Boss/候选描边+图标/字形+编号+类型文字标签
|
||||
func _draw_room(canvas: Control, node: Dictionary, ctx: Dictionary) -> void:
|
||||
var pos: Dictionary = ctx["pos"]
|
||||
var pos: Dictionary = ctx["pos"] # type-hint: ignore(ctx 束 Variant 出值——节点 id → 坐标)
|
||||
var p: Vector2 = pos[node]
|
||||
var t := String(node.get("type", ""))
|
||||
var nid := _id_of(node)
|
||||
|
||||
@@ -141,7 +141,7 @@ func _set_hp(hp: int) -> void:
|
||||
if st._hp_tween != null and st._hp_tween.is_valid():
|
||||
st._hp_tween.kill()
|
||||
st._hp_tween = create_tween()
|
||||
st._hp_tween.tween_property(self, "st.hp_value", target, UiKit.motion(0.15))
|
||||
st._hp_tween.tween_property(st, "hp_value", target, UiKit.motion(0.15))
|
||||
|
||||
|
||||
# 主角/敌方共用——状态效果唯一展示面(壳层伴随件转发;空态 = 图标行隐藏不占位)
|
||||
@@ -212,17 +212,17 @@ func set_pending(ptype: String, pid: String) -> void:
|
||||
# 三档运动签名互异,灰度/剪影层可辨)。摇定时一次性短动画,随后静帧保持。
|
||||
func _play_intent_motion() -> void:
|
||||
var tw := create_tween()
|
||||
tw.tween_property(self, "st._intent_scale", 1.6, UiKit.motion(0.10))
|
||||
tw.tween_property(self, "st._intent_scale", 1.0, UiKit.motion(0.16))
|
||||
tw.parallel().tween_property(self, "st._glyph_rot", 4.0, UiKit.motion(0.10))
|
||||
tw.tween_property(self, "st._glyph_rot", 0.0, UiKit.motion(0.14))
|
||||
tw.tween_property(st, "_intent_scale", 1.6, UiKit.motion(0.10))
|
||||
tw.tween_property(st, "_intent_scale", 1.0, UiKit.motion(0.16))
|
||||
tw.parallel().tween_property(st, "_glyph_rot", 4.0, UiKit.motion(0.10))
|
||||
tw.tween_property(st, "_glyph_rot", 0.0, UiKit.motion(0.14))
|
||||
if _intent_charge:
|
||||
tw.tween_property(self, "st._intent_scale", 1.22, UiKit.motion(0.28)).set_trans(Tween.TRANS_SINE) # ③蓄力缓推
|
||||
tw.tween_property(st, "_intent_scale", 1.22, UiKit.motion(0.28)).set_trans(Tween.TRANS_SINE) # ③蓄力缓推
|
||||
tw.tween_interval(UiKit.motion(0.40)) # 定格微顿
|
||||
tw.tween_property(self, "st._intent_scale", 1.0, UiKit.motion(0.18))
|
||||
tw.tween_property(st, "_intent_scale", 1.0, UiKit.motion(0.18))
|
||||
else:
|
||||
tw.tween_property(self, "st._intent_scale", 1.26, UiKit.motion(0.11)) # ②二次弹跳(高举)
|
||||
tw.tween_property(self, "st._intent_scale", 1.0, UiKit.motion(0.13))
|
||||
tw.tween_property(st, "_intent_scale", 1.26, UiKit.motion(0.11)) # ②二次弹跳(高举)
|
||||
tw.tween_property(st, "_intent_scale", 1.0, UiKit.motion(0.13))
|
||||
|
||||
|
||||
# 资产挂点:tex 落位后字形隐退、纹理立绘顶位——零代码换装契约;tex=null 回退字形。
|
||||
|
||||
@@ -475,7 +475,7 @@ const PANEL_DEFAULT := true # modal_shell 面板哨兵(非 StyleBox 实例
|
||||
# 面板哨兵解析(六参收拢五参——三态:null=无面板〔原 with_panel=false〕/PANEL_DEFAULT=默认样式盒面板
|
||||
# 〔原 with_panel=true+panel_sb=null〕/StyleBox 实例=自定义样式盒面板〔原双参形态〕;
|
||||
# 判别用 is StyleBox——StyleBox 与布尔哨兵直接 != 属异类操作数违例)
|
||||
static func _resolve_shell_panel(panel_sb) -> PanelContainer:
|
||||
static func _resolve_shell_panel(panel_sb) -> PanelContainer: # type-hint: ignore(三态哨兵 bool/null/StyleBox 异构形参)
|
||||
if panel_sb == null:
|
||||
return null
|
||||
var panel := PanelContainer.new()
|
||||
|
||||
@@ -231,8 +231,8 @@ func _ready() -> void:
|
||||
if bv.hover_probe() != seal_t:
|
||||
_problems.append("case① 悬停未到达(_hover=%s 应=%s)" % [bv.hover_probe(), seal_t])
|
||||
var u1 = bv.cells_probe()[seal_t]
|
||||
if not u1.hl_visible or u1.hl_color != UiKit.GOLD:
|
||||
_problems.append("case① 悬停金框缺失(visible=%s color=%s)" % [str(u1.hl_visible), str(u1.hl_color)])
|
||||
if not u1.st.hl_visible or u1.st.hl_color != UiKit.GOLD:
|
||||
_problems.append("case① 悬停金框缺失(visible=%s color=%s)" % [str(u1.st.hl_visible), str(u1.st.hl_color)])
|
||||
if bv.mouse_default_cursor_shape != Input.CURSOR_CROSS:
|
||||
_problems.append("case① 挖掘光标未切十字(%d)" % bv.mouse_default_cursor_shape)
|
||||
# ---- case② 悬停禁入:hover_forbidden 信号 + 灰禁红框 ----
|
||||
@@ -240,14 +240,14 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
if _forbids.is_empty() or _forbids[_forbids.size() - 1] != forbid_t:
|
||||
_problems.append("case② hover_forbidden 未达(%s)" % [str(_forbids)])
|
||||
if bv.cells_probe()[forbid_t].hl_color != UiKit.RED_FORBID:
|
||||
_problems.append("case② 禁入红框缺失(color=%s)" % str(bv.cells_probe()[forbid_t].hl_color))
|
||||
if bv.cells_probe()[forbid_t].st.hl_color != UiKit.RED_FORBID:
|
||||
_problems.append("case② 禁入红框缺失(color=%s)" % str(bv.cells_probe()[forbid_t].st.hl_color))
|
||||
# ---- case③ 悬停已开格:路径预览点迹 + 移动光标 ----
|
||||
_push_motion(_pos(bv, reveal_t))
|
||||
await get_tree().process_frame
|
||||
var dots := 0
|
||||
for c in bv.cells_probe():
|
||||
if bv.cells_probe()[c].dot_visible:
|
||||
if bv.cells_probe()[c].st.dot_visible:
|
||||
dots += 1
|
||||
if dots < 1:
|
||||
_problems.append("case③ 路径预览点迹未亮(dots=0)")
|
||||
@@ -266,8 +266,8 @@ func _ready() -> void:
|
||||
# 掩盖)——有盘断言纹理在槽、缺盘断言字形回退,两分支防双写踩踏复活 ----
|
||||
var seal_unit = bv.cells_probe().get(seal_t)
|
||||
if bv._palette.seal_tex != null:
|
||||
if seal_unit == null or seal_unit.tex_seal != bv._palette.seal_tex:
|
||||
_problems.append("case④b 封印纹理槽未挂封印印记纹理(tex_seal=%s)" % ["无单元" if seal_unit == null else str(seal_unit.tex_seal)])
|
||||
if seal_unit == null or seal_unit.st.tex_seal != bv._palette.seal_tex:
|
||||
_problems.append("case④b 封印纹理槽未挂封印印记纹理(tex_seal=%s)" % ["无单元" if seal_unit == null else str(seal_unit.st.tex_seal)])
|
||||
elif seal_unit == null or seal_unit.glyph != "封":
|
||||
_problems.append("case④b 缺盘字形回退缺失(glyph=%s)" % ["无单元" if seal_unit == null else String(seal_unit.glyph)])
|
||||
# ---- case⑤ 双击 chord:禁入格双左击(核心拒挖零副作用)→ chord_attempted ----
|
||||
@@ -371,12 +371,12 @@ func _ready() -> void:
|
||||
if mark_t.x >= 0:
|
||||
bv.set_variant_mark_resolver(func(_c): return "flat_damage")
|
||||
bv.refresh()
|
||||
if String(bv.cells_probe()[mark_t].mutation_mark) != "flat_damage":
|
||||
_problems.append("case⑭ 变异角标未落位(mutation_mark=%s)" % str(bv.cells_probe()[mark_t].mutation_mark))
|
||||
if String(bv.cells_probe()[mark_t].st.mutation_mark) != "flat_damage":
|
||||
_problems.append("case⑭ 变异角标未落位(mutation_mark=%s)" % str(bv.cells_probe()[mark_t].st.mutation_mark))
|
||||
bv.set_variant_mark_resolver(Callable())
|
||||
bv.refresh()
|
||||
if String(bv.cells_probe()[mark_t].mutation_mark) != "":
|
||||
_problems.append("case⑭ 角标未随 resolver 复位(mutation_mark=%s)" % str(bv.cells_probe()[mark_t].mutation_mark))
|
||||
if String(bv.cells_probe()[mark_t].st.mutation_mark) != "":
|
||||
_problems.append("case⑭ 角标未随 resolver 复位(mutation_mark=%s)" % str(bv.cells_probe()[mark_t].st.mutation_mark))
|
||||
else:
|
||||
_problems.append("case⑭ 无未开格可验(板面异常)")
|
||||
# ---- case⑮ 视野迷雾(三态呈态/半径圈/移动跟随/开关两态零扰动/提灯插值位;
|
||||
|
||||
@@ -281,11 +281,11 @@ func _pick_battle_node(main: Node) -> int:
|
||||
# 入口/兑付停点走 level_screen.open_choices 直传(不写 _pending_candidates)——
|
||||
# 候选从视图态取:_cand_ids × runner.nodes() 的 type(编号解析=node_id_of 单一出口)
|
||||
var ls: Node = main.level_screen
|
||||
if ls._runner == null:
|
||||
if ls._map._runner == null:
|
||||
return -1
|
||||
for nd in ls._runner.nodes():
|
||||
for nd in ls._map._runner.nodes():
|
||||
if String(nd.get("type", "")) in ["battle", "boss"]:
|
||||
var nid: int = ls._runner.node_id_of(nd)
|
||||
var nid: int = ls._map._runner.node_id_of(nd)
|
||||
if nid in ls._cand_ids:
|
||||
return nid
|
||||
return -1
|
||||
|
||||
@@ -129,6 +129,7 @@ tests/
|
||||
| 中文字体随包与字形覆盖 | HUD框架 | `UiKit.load_font()` | `ui_font_asset_test.gd:_init`;`theme_projection_test.gd:_smoke_global_theme` |
|
||||
| 地形瓦片套与格面数字可读 | HUD框架 | `TilePalette.digit_ink_mode()`/`TilePalette.normalize_floor_luma()` | `terrain_tile_sets_test.gd:_test_set_completeness`;`terrain_tile_sets_test.gd:_test_hue_domains`;`terrain_tile_sets_test.gd:_test_digit_ink_modes` |
|
||||
| 站桩敌人呈现与结算演出落点 | 战斗表现 | `BattleStageView.enemy_standee_center()`/`BattleEndOverlay.open_victory()` | `standee_fx_sweep_test.gd:_init`;`pacing_queue_test.gd:_init` |
|
||||
| 调参测速批量模拟(逐帧步进与统计读数) | 调参测量 | `TuneSimController.run()`(调试浮窗批量模拟入口) | `tune_sim_batch_parity_test.gd:_init`(配对对拍套件,随测速循环批建) |
|
||||
| 战斗叙述与终局文案(数值带入/胜负互异) | HUD框架 | `BattleNarrator.battle_end_text()`/`BattleNarrator.boss_name()` | `battle_narrator_test.gd:_test_numeric_lines_carry_values`;`battle_narrator_test.gd:_test_end_text_differs_by_result`;`battle_narrator_test.gd:_test_boss_name_uses_boss_rowset` |
|
||||
| 玩家面文案与危险格格面字形 | HUD框架 | `BoardView.rebuild()`/`StatusSlotRow.set_effects()` | `player_copy_sweep_test.gd:_sweep_board_glyph`;`player_copy_sweep_test.gd:_sweep_legend`;`player_copy_sweep_test.gd:_sweep_hero_panel` |
|
||||
|
||||
|
||||
@@ -478,7 +478,7 @@ func _smoke_save_slots() -> void:
|
||||
fsrc.store_string(JSON.stringify({"version": 7, "meta": {"keystone_balance": 1234}}))
|
||||
fsrc.close()
|
||||
DirAccess.remove_absolute(slot_tpl % 1)
|
||||
ml._migrate_legacy_save(legacy_src, slot_tpl % 1, legacy_src + ".migrated.bak")
|
||||
ml.slots._migrate_legacy_save(legacy_src, slot_tpl % 1, legacy_src + ".migrated.bak")
|
||||
var migrated: Dictionary = JSON.parse_string(FileAccess.get_file_as_string(slot_tpl % 1))
|
||||
Kit.check("sv12 旧档字节迁入槽 1(逐域相等——余额 1234)〔卡① sv12〕",
|
||||
int((migrated.get("meta", {}) as Dictionary).get("keystone_balance", -1)) == 1234)
|
||||
@@ -489,7 +489,7 @@ func _smoke_save_slots() -> void:
|
||||
var fsrc2 := FileAccess.open(legacy_src, FileAccess.WRITE)
|
||||
fsrc2.store_string(JSON.stringify({"version": 7, "meta": {"keystone_balance": 777}}))
|
||||
fsrc2.close()
|
||||
ml._migrate_legacy_save(legacy_src, slot_tpl % 1, legacy_src + ".migrated.bak")
|
||||
ml.slots._migrate_legacy_save(legacy_src, slot_tpl % 1, legacy_src + ".migrated.bak")
|
||||
var slot1_now: Dictionary = JSON.parse_string(FileAccess.get_file_as_string(slot_tpl % 1))
|
||||
Kit.check("sv12 幂等:槽 1 已存在不重迁(预置 777 零覆盖、源保留)〔卡① sv12〕",
|
||||
int((slot1_now.get("meta", {}) as Dictionary).get("keystone_balance", -1)) == 1234
|
||||
|
||||
@@ -17,10 +17,14 @@ class StubTable:
|
||||
return []
|
||||
|
||||
|
||||
class StubDB:
|
||||
class StubCrossrun:
|
||||
var treasure_items: StubTable
|
||||
|
||||
|
||||
class StubDB:
|
||||
var crossrun := StubCrossrun.new()
|
||||
|
||||
|
||||
func _stub_db() -> StubDB:
|
||||
var t := StubTable.new()
|
||||
t.rows = {
|
||||
|
||||
@@ -52,7 +52,7 @@ func _init() -> void:
|
||||
var sv = load("res://core/save_manager.gd").new("user://r1_mech_test_save.json")
|
||||
var mp = load("res://core/meta_progression.gd").new(db, sv)
|
||||
mt.rows = [base_pre.duplicate(true), base_dep.duplicate(true)]
|
||||
db.set("meta_tree", mt)
|
||||
db.crossrun.meta_tree = mt
|
||||
sv.meta_state.set_tree_level("gate_pre", 1)
|
||||
if mp.tree_can_buy("gate_dep"):
|
||||
failures += 1
|
||||
|
||||
@@ -23,6 +23,9 @@ func _init() -> void:
|
||||
|
||||
|
||||
func _trigger_oob() -> void:
|
||||
# 共享 .tres 上的 resolver 归最后装载的实例——autoload ConfigDB 的 _ready 在测试 _init 之后
|
||||
# 二次注入覆盖私有实例,故触发前把解析通道归还被测实例(诊断落 _db,退出码判据才成立)
|
||||
_db.combat.board_gen._resolver = _db._resolver
|
||||
# 越域请求(关卡序号 0 < 合法域 ≥1)——_fatal 内部 push fatal 诊断并 quit(1)(帧末退出)
|
||||
var got: Dictionary = _db.combat.board_gen.resolve_row(0, 0)
|
||||
if _db.diagnostics_count("fatal") >= 1:
|
||||
|
||||
@@ -137,16 +137,16 @@ func _test_shop_accessors(db) -> void:
|
||||
var got: Dictionary = db.run.shop.product_row(String(first.product_id))
|
||||
Kit.check("shop_product_row 按 product_id 精确命中首行", got == first)
|
||||
Kit.check("shop_product_row 未知 id 返回空字典(容错通道)", db.run.shop.product_row("no_such_product_id__").is_empty())
|
||||
var tier_rows: Array = db._shop_rows("gp_drops")
|
||||
var tier_rows: Array = db.run.shop.gp_drops
|
||||
if not tier_rows.is_empty():
|
||||
var tier0: String = String(tier_rows[0].tier)
|
||||
Kit.check("shop_gp_drop_row 按 tier 命中", not db.run.shop.gp_drop_row(tier0).is_empty())
|
||||
var bonus_rows: Array = db._shop_rows("level_gp_bonus")
|
||||
var bonus_rows: Array = db.run.shop.level_gp_bonus
|
||||
if not bonus_rows.is_empty():
|
||||
var blv: int = int(bonus_rows[0].level_index)
|
||||
Kit.check("shop_level_gp_bonus 按关卡序号命中行值", db.run.shop.level_gp_bonus_at(blv) == int(bonus_rows[0].bonus))
|
||||
Kit.check("shop_level_gp_bonus 未登记关卡返回 0(兜底通道)", db.run.shop.level_gp_bonus_at(-1) == 0)
|
||||
var price_rows: Array = db._shop_rows("price_level_bonus")
|
||||
var price_rows: Array = db.run.shop.price_level_bonus
|
||||
if not price_rows.is_empty():
|
||||
var plv: int = int(price_rows[0].level_index)
|
||||
Kit.check("shop_price_level_bonus 按关卡序号命中行值", db.run.shop.price_level_bonus_at(plv) == int(price_rows[0].bonus))
|
||||
@@ -156,19 +156,19 @@ func _test_shop_accessors(db) -> void:
|
||||
|
||||
func _test_meta_accessors(db) -> void:
|
||||
# 无 forge_products 行族断言(行族/访问器不在表,V20 清单)
|
||||
var key_rows: Array = db._meta_rows("boss_keystone")
|
||||
var key_rows: Array = db.crossrun.meta.boss_keystone
|
||||
if not key_rows.is_empty():
|
||||
var klv: int = int(key_rows[0].level_index)
|
||||
Kit.check("meta_boss_keystone_row 按关卡序号命中", db.crossrun.meta.boss_keystone_row(klv) == key_rows[0])
|
||||
var conv_rows: Array = db._meta_rows("conversion")
|
||||
var conv_rows: Array = db.crossrun.meta.conversion
|
||||
if not conv_rows.is_empty():
|
||||
var cattr: String = String(conv_rows[0].attr)
|
||||
var conv_hit := {}
|
||||
for r in db.crossrun.meta.conversion:
|
||||
if String(r.get("attr", "")) == cattr:
|
||||
conv_hit = r
|
||||
break
|
||||
Kit.check("meta.conversion 行集按 attr 命中(访问器退役改直扫同判据)", conv_hit == conv_rows[0])
|
||||
for r in db.crossrun.meta.conversion:
|
||||
if String(r.get("attr", "")) == cattr:
|
||||
conv_hit = r
|
||||
break
|
||||
Kit.check("meta.conversion 行集按 attr 命中(访问器退役改直扫同判据)", conv_hit == conv_rows[0])
|
||||
|
||||
|
||||
# ---- TABLE_MANIFEST ↔ data/tables 目录同步(各系统→D2 单点契约的登记面)----
|
||||
|
||||
@@ -515,10 +515,15 @@ func _smoke_meta() -> void:
|
||||
Kit.check("boss_keystone L1–L3 行连续可达且 first_kill ≥ repeat_kill 全行(首杀全量/重复小额)", boss_ok)
|
||||
|
||||
|
||||
class _MetaStateMock:
|
||||
# 最小元进度件形态——attunement.slots 经 meta_state.tree_state() 读已购等级
|
||||
func tree_state() -> Dictionary:
|
||||
return {"nodes": {"att_socket1": 1}, "fork_sides": {}}
|
||||
|
||||
|
||||
class _TreeSaveMock:
|
||||
# 核代码增补:最小 save 形态——attunement.slots 只读 tree_level("att_socketN")
|
||||
func tree_level(n: String) -> int:
|
||||
return 1 if n == "att_socket1" else 0
|
||||
# 最小 save 形态——attunement.slots 只读 save.meta_state.tree_state().nodes["att_socketN"]
|
||||
var meta_state := _MetaStateMock.new()
|
||||
|
||||
|
||||
func _conversion_row_of(rows: Array, attr: String) -> Dictionary:
|
||||
|
||||
@@ -15,7 +15,7 @@ func _initialize() -> void:
|
||||
|
||||
func _row_by_id(ov) -> Dictionary:
|
||||
var out := {}
|
||||
for r in ov._forge_rows:
|
||||
for r in ov._forge._forge_rows:
|
||||
out[String(r.route_id)] = r
|
||||
return out
|
||||
|
||||
@@ -42,16 +42,16 @@ func _run() -> void:
|
||||
# ① 锁定态:树钥匙未点亮 → 工作间不可见、两区零行板(无任何可交互购买路径)
|
||||
ov.open_camp({"balance": 999, "forge": mp.forge_shop_status(), "tree": []})
|
||||
Kit.check("锁定态:工作间不可见(forge_workshop 钥匙未点亮)〔锻造工坊批 V13〕",
|
||||
not ov._forge_workbench.visible and ov._forge_lock_l.visible)
|
||||
not ov._forge._forge_workbench.visible and ov._forge._forge_lock_l.visible)
|
||||
Kit.check("锁定态:两区零行板(占位纪律——零购买路径)〔锻造工坊批 V13〕",
|
||||
ov._forge_zone_weapon.get_child_count() == 0 and ov._forge_zone_armor.get_child_count() == 0)
|
||||
ov._forge._forge_zone_weapon.get_child_count() == 0 and ov._forge._forge_zone_armor.get_child_count() == 0)
|
||||
|
||||
# ② 解锁态:钥匙点亮 → 两区各三路线
|
||||
ov.open_camp({"balance": 500, "forge": mp.forge_shop_status(),
|
||||
"tree": [{"node_id": "forge_workshop", "level": 1}]})
|
||||
Kit.check("解锁态:工作间可见(钥匙点亮展开)〔锻造工坊批 V13〕", ov._forge_workbench.visible)
|
||||
Kit.check("解锁态:工作间可见(钥匙点亮展开)〔锻造工坊批 V13〕", ov._forge._forge_workbench.visible)
|
||||
Kit.check("两区各三路线(武器锻造区 3 + 护甲锻造区 3)〔锻造工坊批 V13〕",
|
||||
ov._forge_zone_weapon.get_child_count() == 3 and ov._forge_zone_armor.get_child_count() == 3)
|
||||
ov._forge._forge_zone_weapon.get_child_count() == 3 and ov._forge._forge_zone_armor.get_child_count() == 3)
|
||||
var rows: Dictionary = _row_by_id(ov)
|
||||
Kit.check("六路线行册恰全(sword/spear/staff/light/heavy/ward)〔锻造工坊批 V13〕",
|
||||
rows.has("sword") and rows.has("spear") and rows.has("staff")
|
||||
|
||||
@@ -55,6 +55,19 @@ class FakeDriver extends RefCounted:
|
||||
"defeat_node_index": 3, "defeat_node_type": "battle", "hp_left": 0.0, "hp_at_boss": 0.0}
|
||||
|
||||
|
||||
# 假配置库(TuneSimController 只读 db.run.action_economy.ap_per_round——最小域对象图)
|
||||
class FakeActionEconomy:
|
||||
var ap_per_round := 2
|
||||
|
||||
|
||||
class FakeRun:
|
||||
var action_economy := FakeActionEconomy.new()
|
||||
|
||||
|
||||
class FakeDB:
|
||||
var run := FakeRun.new()
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
UiKit.motion_scale = 1.0
|
||||
|
||||
@@ -126,7 +139,7 @@ func _init() -> void:
|
||||
var panel := FakePanel.new()
|
||||
root.add_child(panel)
|
||||
var drv := FakeDriver.new()
|
||||
var ctrl = TuneSimScript.new({"action_economy": {"ap_per_round": 2}}, panel, 100, drv)
|
||||
var ctrl = TuneSimScript.new(FakeDB.new(), panel, 100, drv)
|
||||
drv.ctrl = ctrl
|
||||
await ctrl.run(2) # 假 driver 回调内读 is_running()(两局各一读)
|
||||
Kit.check("控制器运行中 is_running()=true(驱动回调内读数)〔wd8〕", drv.seen == [true, true])
|
||||
|
||||
@@ -802,7 +802,7 @@ func _camp_recent_projection() -> void:
|
||||
var camp = load("res://presentation/views/camp_overlay_view.gd").new()
|
||||
camp.open_camp({"balance": 0, "recent": [
|
||||
{"result": "completed", "levels_cleared": 2, "keystone_total": 5, "master_seed": 42}]})
|
||||
var recent_text: String = String(camp._recent_list.text)
|
||||
var recent_text: String = String(camp._side._recent_list.text)
|
||||
Kit.check("营地最近冒险行完成关数措辞(实际「%s」)〔口径换代 V6〕" % recent_text,
|
||||
recent_text.contains("完成 2 关") and not recent_text.contains("通关"))
|
||||
camp.visible = false
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
# grilling 复核报告——零豁免五卡(2026-10-29,主会话委派)
|
||||
|
||||
状态行:对抗式复核完成。方法=逐卡过审点 A–J(验收三问/对照表两端/静态判据形态/能力行锚定/预算实数/拆分纪律/编队碰撞/行为改动完备性/裁决一致性/可施工性),判据=req-card 必备结构 15 节+code-conventions §1.1+test-conventions §8;证据=五卡 file:line 抽验约 90 处(命中率高,个别 1 行漂移属 T0 兜住范围)+五份设计文档口径核对+architecture v1.25+能力清单逐行核对+gdstyle_baseline.txt 键账清点+迭代 42 在飞两卡触面比对+pipeline_gate 全绿。只读复核,未改任何卡与既有文件。
|
||||
|
||||
## 卡一:gdstyle 尾波补件批(board_hover+breakpoint_store)
|
||||
|
||||
**裁决:有条件成立**(四项编入前须补,均为编辑级补丁,不动拆件方案本身)。
|
||||
|
||||
逐条发现:
|
||||
|
||||
1. 【应修】卡面 §7 编队注记——「与呈现层状态件批同代时**推荐**其先行」,而呈现层状态件批 §3 已把同一约束写死为「已裁……本批先于其 board_hover 半边合回」的硬义务。同一约束两卡一软一硬,编排段按弱措辞排卡会让 hover 拆件落在旧 u.st 写入面上、board_view 改址对账表(单格篇 §5.1)随之失配。改法:board_hover 半边改成硬前置句「呈现层状态件批合回后施工」;breakpoint_store 半边明示不受此限、可独立先行。
|
||||
2. 【应修】§8 V1 判据绑定面写「格件 **st** 边框/点迹字段」——本卡自认编排在状态件批之后,届时该读面已改 u.face.*(ui_input_probe 四处改址为状态件批 V4 行),判据面描述按施工时点必陈旧。改法:改写为「格件状态件边框/点迹字段(状态件批合回后=u.face.*)」。
|
||||
3. 【应修】§3 现状事实「公开入口 `resume_adventure`(:94)」行号错——实查 :94 是 start_adventure,resume_adventure 在 adventure_runner.gd:141。改法:改 :141(T0 重锚虽会兜住,现状事实按规约须代码级准确)。
|
||||
4. 【应修】§13 预算节「预算 2(_hover/_last_click)**+引用束成员**」「预算 6……**+引用束**」未给引用束成员数,复核门无法对账 ≤15。按 §7/T2 构造面推算 board_hover 约 7(2+cells/minesweeper/diggable+2 Callable)、breakpoint_store 约 14(6+db/rng/主角账三件/curio/stop/bank/loadout)——均达标但后者贴顶。改法:把引用束成员逐一列名计数写进预算表。
|
||||
5. 【可接受申报】V1 零漂移证明全压既有断言面;悬停 11 函数族中 chord 双击首遇锚(board_view.gd:475 _detect_chord)在「棋盘悬停反馈」三语义行与 ui_click_probe 之外无显式断言,属既有覆盖缺口。零行为改动批不为既有缺口补测不违规,实现报告宜记一句该缺口。
|
||||
6. 核验通过项:A 两行对照表三问可答(真实入口/判据面/能力行齐);C 对照表零静态行;E 键账全对(board_view 32 实数清点吻合、−2=约30;adventure_runner 28 清点吻合、−6=约22;断点域 6 成员与 9 函数族 file:line 全命中;BREAKPOINT_FIELDS :539 起、breakpoint_resume_test.gd:185 命中);F 拆分职责语句在位、_r0 留宿主防凑计数袋论证成立(board_view.gd:238/:296/:563 三消费方实查);G 与迭代 42 的 board_view 触面已声明、编入待其合回;I 与裁决①②⑤一致(D5 留债、禁落豁免登记、_r0 留宿主);J 一步一动作、无 TBD 类句式。
|
||||
|
||||
## 卡二:组合根注册面批(main 49→15)
|
||||
|
||||
**裁决:有条件成立**(一项 blocker 级必改+两项应修;机检与数字面全过,方案本身成立)。
|
||||
|
||||
逐条发现:
|
||||
|
||||
1. 【blocker】§1 编队注记「与迭代 42……**无文件交叠(main.gd 与探针不在其触面)**」与盘面矛盾——在飞并排卡 `reports/需求卡片-level_runner商店委托层拆除-2026-10-29.md` 文件清单明确含 game/presentation/main.gd(改址 1 处)、main_adventure_flow.gd(6 处)、main_overlay_flow.gd(2 处),三者全在本卡触面集(main.gd+三流程件)。用户裁决④要求五卡编队碰撞约束与迭代 42 自洽,此句是失实声明,编排段靠它排卡。改法:改为「与迭代 42 商店委托层拆除卡在 main.gd/main_adventure_flow/main_overlay_flow 三文件有改址点交叠——待其合回后开工,T0 映射表生成时并核其改址点」;T0 步骤同步补一句。
|
||||
2. 【应修】§8 对照表第 2 行与第 11 行内含静态判据(S13 键账对账「main.gd 实测 15」、grep 残留=0)——姊妹卡三/四/五均已把静态键账判据按 test-conventions §8.4 出口移出对照表(在域口径段申报),本卡两行在表内带静态成分,形态不一致。改法:静态部分移入 §8 域口径静态申报段,行内只留行为主证(双宿主摘要/全量闸回执)。
|
||||
3. 【应修】转发壳清点漏一件:main.gd:516 `main._flush_row_queue()`(纯转发 `_row_pacer.flush()`,消费方 pacing_queue_test.gd:103+main 内部两处注记)不在「七别名+六转发方法」清单——_row_pacer 迁 ui.screens 后该 Middle Man 壳归宿未声明,与本批净消灭转发壳的方向不一致。改法:表 C/表 D 补一行(退役并改址消费方,或写明保留理由)。
|
||||
4. 【可接受申报】V4(探针批量改址)与 V10(render_gate)的能力行锚取九探针中单点代表行(棋盘悬停反馈/站桩敌人呈现),语义为最小可得锚且未逐行披露该局限。建议 §8 域口径补一句「探针/渲染行能力锚取代表行」。
|
||||
5. 核验通过项:A 十一行全齐;E 数字全对平——main.gd 49 个 var 实数清点吻合(grep ^var 恰 49)、49=28 迁(表 A 9+5+14)+14 留(表 B)+7 消灭(表 C)+1 新增=15;四新件预算(2/0/0/1 公开方法、3/9/5/14 成员)与 §7.2 接口块逐名一致;LAYER_CONTRACT :39 起、六转发方法 :156/:161/:282/:285/:288/:292、别名七件行号全命中;smoke_boot 六处 get()=4 改 2 留逐字吻合;pacing_queue_test :108/:132/:147/:149、source_guard V1d :69-77、theme_projection V6 :724-725、system_test V1c/V2 :94-109 全命中;D 能力行六名全在 game/tests/README.md 且受影响行核对成立;F §12 复用排除论证(ModalFlow/ModalStack/ui_assembler/run_scope 逐一否决+ConfigDB 三容器先例)充分;唯一面实查成立(game/presentation/ 下四名未建、仅 ui_assembler 在册);I 与裁决①③一致(零豁免、注销句、净消灭);J 估时 3–4 日在冻结线内、步骤全部可核查。pipeline_gate 机检 13 卡全过。
|
||||
|
||||
## 卡三:战斗编排归约批(RoundCycle+BattleFacts,38→15)
|
||||
|
||||
**裁决:有条件成立**(一项应修算术错;其余全过,是五卡中证据密度最高的一张)。
|
||||
|
||||
逐条发现:
|
||||
|
||||
1. 【应修】§4 红线句内部算术矛盾:「已迁 **22** 成员声明随迁即删(**21** 迁两件+treasure_inventory 退役+_hero_atk 退役)」——21+2=23≠22。实数=迁两件 22(BattleFacts 15+RoundCycle 7)+退役 2=删声明 24 项;轴丙后宿主 37→13 旧留+2 新=15,账平。architecture v1.25 两行写「收编 7+14=21」与本卡 BattleFacts 15 名单的 1 名口径差,已由 §6 反哺点通道(「批末成员数实测值与在册数字出入」)覆盖,但本句数字须改正以免实现期对账混乱。改法:改「22 迁两件+2 退役」。
|
||||
2. 【可接受申报】encounter 归 BattleFacts 最弱格标注诚实:设计文档 §6 白纸黑字「它也是本方案最弱的一格」+两条备选砍路(nest_preview_count 解冻/_reward_economy 经授予件中转)均判更差;卡内 L3② 给出实现期证伪的停卡出口、§4 给出 15/15 贴顶与 SealLedger 扩容阀、设计 §8 险点 8 处理了 BoardInstaller bundle 键 encounter 传 _facts.encounter 的同引用零冲突——无隐瞒。
|
||||
3. 核验通过项:A V0–V6 七行齐(V2 复位边界险点单独配断言、判据绑两快照同键值恒等);E 类变量 38 实数清点吻合(:37-85+:223-227 逐名)、基线两条类级键与「零函数级键」实查一致、保留 15 名单/两新件 8+15 成员账全平;file:line 抽验约 20 处全命中(treasure_inventory setter :48-52、外部注入 level_runner.gd:520、宿主四读 :111/:203/:450/:858、grant_segment :370-371、combat_segment :56、settle_segments_test :27 接线断言原文、static_scan S8 :317/S7 :359 九文件清单、run_all_gates PARITY 清量 battle_orchestrator :169、五段构造/三闸/摇号/复位块/完美谓词行号);C 静态判据(键账收敛、S7/S8 增行)已按 §8.4 出口移出对照表在域口径段申报;D 十三处能力行全部在 README 在场且语义对题(V0 锚「回放确定性」为精确锚);F 两新件职责语句+集体身份在位(「持段件者不能是被持者」「事实账不是授予物」)、已否决切法留档;G 编队前置「迭代 42 合回之前禁开工」覆盖与在飞两卡在 battle_orchestrator/level_runner/static_scan.sh/treasure_effects_test 等的全部触面交叠;I 与裁决①③⑤一致;J 估时 2.5–3.75 对设计 §12 的 2–3 日给了上探理由,PARITY 批内实跑须用户点头不占估时。
|
||||
|
||||
## 卡四:呈现层状态件批(单格两域件+站桩两件,30→10/19→10)
|
||||
|
||||
**裁决:有条件成立**(一项应修编队漏声明;潜伏红处置路径成立,成员拆分账五卡中最难算、已全对平)。
|
||||
|
||||
逐条发现:
|
||||
|
||||
1. 【应修】与卡二在 game/probe/ui_input_probe.gd 的**同文件交叠两卡均未声明**:组合根注册面批改该探针的 main.X 地址面(:34-43 等约 867 处散布之一),本批改四处 u.face.* 直读(:234-235/:243-244/:250/:374-379)——行位不相交但同文件,两卡又是同一条目(零豁免五键清偿批四卡)的同代候选,编排段靠编队声明排卡,此漏会制造二次 T0 重锚。改法:两卡编队注记互写一句(本卡补「与组合根注册面批在 ui_input_probe.gd 有触面交叠,先后施工各自 T0 重锚」,卡二同步)。
|
||||
2. 【可接受申报】潜伏红 T0 定谳路径诚实:四处直读实查确在探针源码、迭代 41 已把 hl_visible/hl_color/dot_visible/mutation_mark 迁入内嵌类 _CellPaintState(board_cell_unit.gd:27 起),宿主 Node2D 无同名属性,「Invalid get index」推演成立;卡内预设 L3③「实跑全绿=证伪设计前提=停卡」的出口——未把推断当已证事实写死,定谳义务落在 T0 实跑。
|
||||
3. 【可接受申报】V4 能力行锚「棋盘悬停反馈」含 case⑭ 变异角标(非悬停三语义)的最小拉伸;同一探针同一入口,可接受。
|
||||
4. 核验通过项:A 四行齐(V1/V2 golden 主证、V3 演出链、V4 悬停金框/禁入红框/路径点迹/变异角标四处断言面);E 成员账全对平——内嵌类 27 名实数清点吻合、基座 12(11+_owner)+叠加 13(12+_owner)+宿主上收 edge/cell/glow_group+原位 glyph/glyph_color/plate/fog_state/_glow_layer+base/face=宿主 10;站桩真实 25=vitals 11 名+motion 10 名+原 _owner+3 计数器、宿主 10=5 冻结 var+st+mo+3 计数器;31/33 全文件声明数与 :26-122/:125-143、:23-59/:62-68 分区实查一致;九常量 :12-23 逐字命中;C 静态键账判据已按出口移出对照表(§9 域口径段申报,五卡中形态最规范);D 六处能力行全在场且语义对题;F 四新件职责语句+逐件排除论证(TilePalette/HeroSprite/BoardWorld/battle_stage_view/StatusSlotRow)在位,迷雾留宿主的「唯一不产生跨件回引」论证成立;G 与迭代 42 的 board_view 五段改型耦合声明完整(T0 前置+「先于尾波补件批 board_hover 半边合回」反向义务);gdstyle 截断缺陷红线(禁利用截断口径降数、禁把 _portrait_tex 当削减目标)与裁决一致;golden 三张禁换锚禁重制。
|
||||
|
||||
## 卡五:测速循环批(信号步进状态机+双实现对拍)
|
||||
|
||||
**裁决:有条件成立**(一项应修能力行悬置;对拍方案与申报形态是五卡中最完整的)。
|
||||
|
||||
逐条发现:
|
||||
|
||||
1. 【应修】能力行锚语义错位且专属行悬置无主:三行对照表能力列锚「站桩敌人呈现与结算演出落点」,该行语义是站桩呈现与终局演出(README 旅程段六,系统列=战斗表现),与本批测量面(批量模拟逐帧步进/运行态贯穿/报告注入)不同域;卡内自承「测量面专属能力行=写卡段后续处理」——但写本卡的会话**就是**写卡段,2026-10-29「当场入表」规则下该行应随本卡增行(真实入口=debug_overlay press_simulate_for_probe() 按钮 pressed 信号链→run(n);代表用例=standee_fx_sweep_test.gd:_init〔wd8〕+tune_sim_batch_parity_test.gd:_init),增行后本列改锚。悬置写法让义务无承载主体、批末无人对账。
|
||||
2. 【可接受申报】行为改动申报完备性成立:全件 68 行实读核对——:67-68 确为每局置假(潜伏红本体),静态矛盾推演(drv.seen=[true,false]、探针守卫环同段退出四串全红)与源码逐句吻合;改形其余面(常驻连接/is_connected 守卫/首步同步/n=0 同步收尾/_step_frame else 先断连)核为非行为改动;「_finished 若零读者可删」方向是删不是留,不违禁为机检保留成员条款。
|
||||
3. 【可接受申报】脚本错误中断路径差异按 §8.4 出口声明缺口(协程死亡静默停摆 vs 确定性错误逐帧重试),T3 文档化义务在位,未伪装成可证判据;两形态测量批遇错都整批作废、同级不同形的论证成立。
|
||||
4. 核验通过项:A 三行齐且真实入口真实(wd8 假驱动回调内读 is_running()、探针真实按钮信号链);E 键账预算表逐规则落卡、成员 5+6=11(信号计入则 12)账与 T1 名单吻合、_run_one_level 5 参临界持平声明在位、改造后全文件零循环键消除逻辑成立(结构性免疫);file:line 全量命中(run :36-52、循环 await :50、FakePanel/FakeDriver、wd8 三断言与〔wd8〕尾缀、ui_tune_probe SIM_GUARD_FRAMES=1800 :16 与 :63-83 四串断言、debug_overlay is_running :77/set_sim_running :81/_sync_sim_button :107、main_debug_flow :72-77 不 await 形态与 :84 互查守卫、hud_presenter 空守卫与 maxi(1,n));C 静态判据与声明缺口均不入对照表;F 零拆出单元的「不拆理由」在位(步进机是私有运行机制、拆出命不出职责语句=凑计数袋,§8 引 code-conventions ②④);遗留 await 形态副本全仓唯一性+夹具不入四扫描面的声明经实查成立(基线 :15 唯一键、S8 九文件不含本件);G 与其余四卡及迭代 42 无产品码触面交集声明成立(run_all.gd manifest 潜在交叠已交编排段);I 与裁决③④⑤逐条一致(双实现对拍入批、收尾还原作为已申报行为改动、错误路径接受并文档化);J 估时 1–1.5 日合理,T0 定谳证据列为审计第③项必查项。
|
||||
|
||||
## 总表
|
||||
|
||||
| 卡 | 裁决 | blocker | 应修 | 可接受申报 |
|
||||
|---|---|---|---|---|
|
||||
| 卡一 尾波补件批 | 有条件成立 | 0 | 4 | 1 |
|
||||
| 卡二 组合根注册面批 | 有条件成立 | 1 | 2 | 1 |
|
||||
| 卡三 战斗编排归约批 | 有条件成立 | 0 | 1 | 1 |
|
||||
| 卡四 呈现层状态件批 | 有条件成立 | 0 | 1(与卡二共担) | 2 |
|
||||
| 卡五 测速循环批 | 有条件成立 | 0 | 1 | 2 |
|
||||
|
||||
全库 blocker 与应修清单(编排段放行前置):
|
||||
|
||||
- **blocker(卡二 §1)**:编队声明失实——「与迭代 42 无文件交叠(main.gd 不在其触面)」被在飞商店委托层拆除卡的文件清单(main.gd/main_adventure_flow/main_overlay_flow)直接证伪,须改写为如实交叠声明+开工前置。
|
||||
- **应修(卡二+卡四,跨卡)**:ui_input_probe.gd 同文件触面交叠两卡编队注记均未声明,互写一句补齐。
|
||||
- **应修(卡一 §7)**:board_hover 半边的状态件批先行约束从「推荐」升为硬前置,与卡四侧已裁义务对齐;breakpoint_store 半边明示可独立先行。
|
||||
- **应修(卡一 §8)**:V1 判据绑定面「格件 st 边框/点迹字段」按施工时点改 u.face.* 口径。
|
||||
- **应修(卡一 §3)**:resume_adventure 行号 :94 改 :141。
|
||||
- **应修(卡一 §13)**:预算节引用束成员列名计数(board_hover 约 7、breakpoint_store 约 14)。
|
||||
- **应修(卡二 §8)**:对照表第 2/11 行静态判据移入域口径申报段,与卡三/四/五形态统一。
|
||||
- **应修(卡二 表 C/D)**:main._flush_row_queue(:516)转发壳归宿补声明(退役改址或保留理由)。
|
||||
- **应修(卡三 §4)**:「已迁 22 成员(21 迁两件+2 退役)」算术改正为「22 迁两件+2 退役」。
|
||||
- **应修(卡五 §6/§12)**:测量面专属能力行随本卡当场增入 game/tests/README.md 并改锚三行能力列,废「写卡段后续处理」悬置表述。
|
||||
|
||||
总体判断:五卡可以进编排段,但须先落上表一项 blocker 与九项应修——全部是编辑级补丁与声明修正,无一张需要推翻拆件方案或重做设计。证据面结论:五卡 file:line 抽验约 90 处命中(唯一硬伤=卡一处行号),键账与成员迁移账全部数平(含卡四最难的 27/25 内嵌类双 _owner 拆分),两处静态矛盾推演(卡四潜伏红、卡五每局置假)经源码逐句复核成立,与五项用户裁决无一冲突,机检 pipeline_gate 全绿。最大的真实风险不在卡内而在编队声明层:卡二对迭代 42 的无交叠声明失实、卡二与卡四未声明探针同文件交叠——这两处修正后,编排段才有可信的排卡依据。
|
||||
@@ -0,0 +1,36 @@
|
||||
# 迭代 41 测试债批——实现报告(2026-10-29)
|
||||
|
||||
**接收方**:待办清单原「迭代 41 测试债修复——9 个套件失败与静态扫描三项红」条目(随本批完成整条删除,本报告为收尾凭据)。
|
||||
**改动面**:游戏代码(worktree 批)。
|
||||
**执行**:worktree `g-plan2-testdebt-20261029`(分支 `testdebt-20261029`,自 master cf0e40cc 分出,批内 `git merge master` 到 39c1fc69 后跑闸),提交 215da315/413124b0/afd1a41f,合并提交 43906cdd;工作区与分支已删除。
|
||||
|
||||
## 一、登记范围完成度
|
||||
|
||||
| 登记项 | 结果 |
|
||||
|---|---|
|
||||
| 02 九套件失败 | 全部归绿(65 套件全跑,`[run_all] 0 个套件失败`) |
|
||||
| S9 类型闸 24 处 | 归零——`node_map_generator` 三处给真类型(`Array[int]` 贯通 `_vo_flow_facts`→`_build_trunk`),其余 21 处为动态边界(Variant 出值/鸭子型注入/异构 Callable 束),按 V7 白名单逐处补 `# type-hint: ignore` 并写明理由 |
|
||||
| S10 文件头 4 处 | 归零——`config_db` 与三张域容器头注去日期 |
|
||||
| S11 注释禁用词 1 处 | 归零——`adventure_table.gd:55` 档位退役词「罕见」改现行「稀有」 |
|
||||
| 死常量 `SCHEMA_VERSION` | 已删(全仓零引用;文档侧「表结构版本」冲突面已由文档批清偿) |
|
||||
|
||||
## 二、实测扩出的范围(登记条目未预见,全部由代码域闸实跑暴露)
|
||||
|
||||
登记时 03/04/05 三闸在能力审计上电批被记为 SKIP(测量面批口径),其红项从未被实测过,故条目只记了 02 与 09。本批按代码域实跑,三闸皆红,逐条追因如下——**四处是迭代 41 特许直接合回留在产品码里的运行期断链,不是测试债**:
|
||||
|
||||
1. **数字色牌守卫丢失**(`game/presentation/views/board_cell_unit.gd` `_draw_glyph_layer`):迭代 41 卡②绘制分层时把 `if plate:` 判据丢掉,变成「凡有字形即垫牌」。后果=dungeon 关数字(本应亮墨直画在棕底)一律落到奶油色牌上。判据=棋盘 golden 逐像素:L1_dungeon changed=2.74% 超容差、L2/L3 与菜单 0.00%;恢复守卫后 L1 回 0.00%(与迭代 37 换代基线逐像素一致)。墨族自适应实测读数同时佐证现行口径:dungeon `plate=false`(亮族对比度 4.79/5.80 过门槛)、underdark `plate=true`(深族均值 2.41 不过门槛)。
|
||||
2. **`open_victory` 第 4 参未随 opts 改型**(`game/presentation/curio_interact_controller.gd:79`):迭代 41 卡②把该函数的四散参数收拢为 `opts := {}`,其余调用方(`main.gd`/`main_adventure_flow.gd`)已改,此处仍传字符串 → 运行期 `Cannot convert argument 4 from String to Dictionary`,关卡完成三选一停点与续玩恢复路径的胜利总结面开不起来(探针报「三选一停点分支中断」)。改型为 `{"gp_summary": …}`,串内容与改前逐字同。
|
||||
3. **站桩补间目标写错**(`game/presentation/views/standee_body.gd`):状态收进内部件 `st` 后,9 条 `tween_property(self, "st.xxx", …)` 的属性路径不成立(引擎报 `The tweened property ... does not exist`,并连带 `set_trans` 落在 null 上)→ 血量条与三档意图动效全静。改为直接补间子对象 `tween_property(st, "xxx", …)`。
|
||||
4. **调参批量模拟运行态收尾位置**(`game/presentation/tune_sim_controller.gd`):循环体提函数时把 `set_sim_running(false)`/`_running = false` 搬进了单局函数,等于每局结束就宣布模拟结束——面板置灰与组合根互查守卫在剩余局数内失效。归还到 `run()` 末尾。
|
||||
|
||||
另有探针面随拆件改址(断言零删减、零放宽):`ui_input_probe` 格面成员入 `st` 六处、`ui_struct_probe` 的 `level_screen._runner` → `._map._runner`;测试面改址九处(`slots`/`meta_state`/`crossrun`/`_forge`/`_side`/`_meta_rows`→表成员直读/`_shop_rows`→表成员直读)。
|
||||
|
||||
## 三、闸与回执
|
||||
|
||||
`tools/run_all_gates.sh --code`(域=code、scope=full、dirty_game=false):00 冒烟/01 系统测试/02 单元与集成/03 探针 --click/04 探针 --full/05 渲染闸/09 静态扫描/10 熵增闸全部退出 0;11 回放确定性对拍按触面判定 SKIP(本批未触数值·存档·RNG·结算)。与基线比对=**零新增红**,且 02、09 两闸「基线红 → 现绿(改善)」,`all_green=true`。合回后主区两件秒级事已过:`--editor --quit` 重刷类名缓存、冒烟 15 项 0 失败。
|
||||
|
||||
## 四、遗留与待裁
|
||||
|
||||
1. **闸基线 02/09 两键待换代**:两键仍记本批已消除的存量红指纹,未来若回归到同一红项会被判「存量红·零新增」而静默放行。换代须改 `game/tests/.gates/baseline.json`(代码面)→ 已另立待办条目,随下一个代码批一并落。
|
||||
2. **architecture.md 残留常量名**:`design/engineering/architecture/architecture.md:88` 的 ConfigDB 行仍把 `SCHEMA_VERSION` 列为该类职责,常量已删,该句失真——属文档面反哺点,待文档批按「删该词或改现役 `SAVE_FORMAT_VERSION`」落文(本批为实现批,禁写 `design/`)。
|
||||
3. **实机目检**(归用户,不阻塞):dungeon 关胜利后数字回到棕底直画(无奶油牌);关卡完成三选一停点的胜利总结面能正常开出并可继续;调参面板批量模拟期间浮窗置灰、结束后解除。
|
||||
@@ -0,0 +1,134 @@
|
||||
# 需求卡片——gdstyle 尾波补件批
|
||||
|
||||
> **版本状态**:v1.0 定稿——零待裁点(2026-10-29 用户裁:恢复尾波卡 v2.0 裁去的 D2/D4 两拆件项;D5 五降值键=留债、零豁免延伸)。
|
||||
> **接收方**:待办清单条目「gdstyle 尾波补件批——悬停域与断点域拆件(2026-10-29 登记)」。
|
||||
> **来源**:尾波清偿批设计闭合后的用户再裁(D2/D4 改判拆件)。**唯一事实源**:`design/engineering/architecture/architecture.md` v1.25(「模块归属·呈现层」表 board_hover 行、「核心层」表 breakpoint_store 行、「冒险域拆分」节断点随动句、「呈现层装配」节屏成员寻址句)。
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
这批做什么:把尾波卡 v2.0 裁去的两个拆件项恢复执行——board_view 悬停域拆出 board_hover、adventure_runner 断点域拆出 breakpoint_store。三个 gdstyle 键随之降值(board_view 类变量 32→约30、adventure_runner 类变量 28→约22;board_view 公开方法 27 持平——全为契约面)。
|
||||
|
||||
什么状态算完:
|
||||
|
||||
1. 两新件在库、宿主成员迁出、键账达第 3 节预期(降值口径,不承诺清零)。
|
||||
2. 行为零变化:同种子下事件流、断点快照、棋盘渲染逐位一致。
|
||||
3. 批末代码域闸全绿;三键终值按留债口径记入实现报告(禁落 architecture 豁免登记)。
|
||||
|
||||
## 2. 设计事实源
|
||||
|
||||
architecture.md v1.25 三处在册设计(2026-10-29 零豁免裁设计闭合):board_hover 行(职责语句「悬停预承诺呈现域」、拟收 11 函数族+2 成员、耦合边界)、breakpoint_store 行(职责语句「存档断点组装与回放唯一承载」、拟收 6 成员+函数族、27 键冻结)、「冒险域拆分」节随动句(拼盘与读侧策略机组拆出、应用层落盘口不变)。
|
||||
|
||||
## 3. 现状事实(2026-10-29 实查;行号为迭代 42 合回前基线——T0 必须按当轮 master 重测重锚,board_view 的 `_paint_cell` 届时已由迭代 42 拆为五段、行号必漂移)
|
||||
|
||||
- board_view.gd:悬停域成员 `_hover`(:70)、`_last_click`(:71);函数族 11 个=`_hover_at`(:442)、`_on_shell_mouse_exited`(:453)、`_detect_chord`(:475)、`_on_cell_hover`(:486)、`_on_cell_unhover`(:491)、`_refresh_hover_after_paint`(:497)、`_apply_hover_visuals`(:503)、`_clear_hover_visuals`(:531)、`_set_cursor_shape`(:538)、`_show_path_preview`(:542)、`_hide_path_preview`(:552)。`_r0`(:72)是出生展开区资格域成员(:238/:296/:563 三消费方),**不随迁**——划入悬停件即凑计数袋。
|
||||
- adventure_runner.gd:断点域成员 6 个=`_save_manager`(:35)、`_resume_bp`(:36)、`_pending_next_level`(:30)、`_last_level_payload`(:31)、`_last_treasure_cleared`(:32)、`_loadout_seeded`(:37);常量 `BREAKPOINT_FIELDS`(:539-568,27 键);函数族=`_snapshot_breakpoint`(:571)、`_bp_parts`(:583)、`_bp_read`(:636)、`_bp_strategy`(:646)、`_bp_read_int`(:651)、`_resume_ledger`(:182)、`_resume_curio_state`(:193)、`_resume_params`(:218)、`_resume_counters`(:237);公开入口 `resume_adventure`(:141;:94 为 start_adventure)留宿主薄壳。
|
||||
- 测试触面:`game/tests/unit/core/breakpoint_resume_test.gd:185` 直读 `AdventureRunnerScript.BREAKPOINT_FIELDS`——随件迁改址(判据零变化)。
|
||||
- 键账:board_view 类变量 32(键留债目标约 30)、公开方法 27(持平——27 个逐类核对全为探针契约面与依赖单向纪律承载面);adventure_runner 类变量 28(留债目标约 22)。
|
||||
|
||||
## 4. 设计契约(违反即返工的红线条款)
|
||||
|
||||
- 🔴 **行为零变化**:同种子下事件流/断点快照/存档往返/棋盘渲染逐位一致;玩家可见面零变化。
|
||||
- 🔴 **断点键集冻结**:`BREAKPOINT_FIELDS` 27 键逐键冻结(键名、策略标签、键序零变化);随件迁移只换承载文件,不换键面。
|
||||
- 🔴 **RNG 零触碰**:本批零新流、零消费序变化(断点回放 restore 同序取号;悬停域无随机)。
|
||||
- 🔴 **呈现零变化**:悬停反馈三语义(光标/边框/路径预览)行为逐点保持;棋盘 golden 三张对拍差异非零即红。
|
||||
- 🔴 **拆分边界纪律**(判据权威=code-conventions §1.1,卡内执行条款):①拆出单元须有职责语句与单一变化原因(实现报告逐件一行);②集体身份——命不出名字的打包=凑计数袋,禁;③「过阈值」只作发现信号;④拆不出内聚单元→停卡呈报;⑤禁沿阈值轴拆。
|
||||
- 🔴 **禁为机检文本保留无效成员**:禁止为迎合机检消息文本保留或新增无效成员/别名;机检键与卡片契约互斥=停卡呈报。
|
||||
- 🔴 **残留键留债(D5 零豁免裁)**:三键降值后留基线冻结禁恶化;**禁落 architecture 豁免登记**;禁为凑阈值硬拆。
|
||||
|
||||
## 5. 范围边界
|
||||
|
||||
做什么:第 3 节两拆件项(board_hover、breakpoint_store)。
|
||||
|
||||
不做什么:迭代 42 在飞范围零触碰(_paint_cell 拆五段、循环内 new、_enter_node、商店委托壳——并排卡承接);单格/站桩状态件(呈现层状态件批承接);main.gd/battle_orchestrator/tune_sim 五键(零豁免五键各批承接);三残留键的终局清偿(留债,后续窗口再议)。
|
||||
|
||||
## 6. 关联文档同步面
|
||||
|
||||
| 文档 | 关联点 | 同步义务 |
|
||||
|---|---|---|
|
||||
| design/engineering/architecture/architecture.md | 两新件登记行(建件后「实现批建件」改现状);「冒险域拆分」节随动句核对 | 设计权威文档——实现批禁直改;逐条列进 `reports/iter<N>-反哺点-<日期>.md`,用户裁决后归文档批落文 |
|
||||
| game/tests/README.md | 「棋盘悬停反馈」行代表用例列(本批复用既有探针、零新增断言——预计零改动);断点行入口句核对 | 机械面文档——实现批禁写;如需更新由写卡段后续卡修订版同批处理 |
|
||||
| design/gdd/systems/ | 无关联文档——结构整改不改游戏规则与玩家可见行为 | 无修订预期;契约句被触碰=停卡呈报走反哺点通道 |
|
||||
|
||||
## 7. 任务卡 T0..T3
|
||||
|
||||
**T0 读数重锚与对账(0.25–0.5 工作日)**
|
||||
|
||||
- [ ] 以当轮 master 重测 board_view/adventure_runner 三键实测值与第 3 节全部 file:line;漂移处就地改卡并记录;对不上即停卡呈报
|
||||
- [ ] 复核 11+9 函数族现行键面(`tools/gdstyle_baseline.txt` 无其函数级键——逐字搬运零新键;实查确认)
|
||||
|
||||
**T1 board_hover 拆件(0.75–1 工作日)**
|
||||
|
||||
- [ ] 建 `game/presentation/views/board_hover.gd`(RefCounted;构造=引用束注入:cells 容器引用、minesweeper 只读引用、diggable 集合引用+壳层光标写入与 hover_forbidden 注入 Callable)
|
||||
- [ ] 悬停函数族 11 个+成员 `_hover`/`_last_click` 迁出(函数体逐字搬运);三入站口(`_gui_input`/`_on_cell_input`/`click_cell`)留宿主委托;`hover_probe()` 留宿主读件投影(返回语义零变化);`_r0` 留宿主
|
||||
- [ ] 孤立验证:`tools/probe_gate.sh --click`+`--full` 全绿;`tools/render_gate.sh` 棋盘 golden 三张差异 0.00%(非零即停机呈报)
|
||||
|
||||
**T2 breakpoint_store 拆件(1–1.5 工作日)**
|
||||
|
||||
- [ ] 建 `game/core/breakpoint_store.gd`(RefCounted;构造=引用束注入:db、rng、主角账三件、curio/stop/bank/loadout 引用——防 max-parameters 新键)
|
||||
- [ ] 断点域 6 成员+`BREAKPOINT_FIELDS`+函数族 9 个迁出(逐字搬运);`resume_adventure` 留宿主薄壳;`set_save_manager` 转发件
|
||||
- [ ] `breakpoint_resume_test.gd:185` 改址为 breakpoint_store 常量(判据零变化——第 14 节申报)
|
||||
- [ ] 孤立验证:`--script res://tests/run_all.gd -- --only=breakpoint_resume,save_rng_roundtrip,cross_system_flow` 全绿+`python tools/run_smoke.py`
|
||||
|
||||
**T3 键账对账与收口(0.5 工作日)**
|
||||
|
||||
- [ ] 批末代码域闸全绿(`tools/run_all_gates.sh --code`)
|
||||
- [ ] 三键终值对账(board_view 约30/27、adventure_runner 约22)——留债口径记入实现报告
|
||||
- [ ] 产出物落位卡:实现报告与反哺点清单写齐方算收口
|
||||
|
||||
合计估时约 2.5–3.5 工作日。编队注记:编入待迭代 42 合回;**board_hover 半边硬前置=呈现层状态件批先合回**(该批改型 u.st 写入面后,hover 拆件在新写入面上施工——grilling 复核定级,原「推荐先行」升格);breakpoint_store 半边无此依赖,可独立先行。另:本卡与组合根注册面批共享 ui_input_probe.gd 触面(该批改 main.X 地址面、本批不改探针内 u.face 读面)——同代编排时先后皆可。
|
||||
|
||||
## 8. 验证闸——改动—验收对照表
|
||||
|
||||
域口径:本批改动全为 `game/` 下非 .md 行为载体——批末跑代码域闸;里程碑步(T 段)出口跑一次全套闸,波内修复只做出红最小单元的最窄确认,新增测试先行孤立验证再并入全套。总判据=每行改动以「既有断言面全绿+golden 零差异」证明零行为漂移;全量闸电池=冒烟+系统测试+run_all 全量+probe_gate --click --full+render_gate+static_scan(含 S13 对账)。
|
||||
|
||||
| 行 | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| V1 | 悬停域拆件 | board_hover.gd 新建;board_view.gd 函数族与 :70-71 成员迁出 | 复用 ui_input_probe 悬停三语义断言(case①到达/②禁入/③路径预览)+ui_click_probe+type_glow_shot_probe;新增断言零条 | 探针 | 合成 InputEventMouseMotion/MouseButton 经 `_gui_input` 入站口;`hover_probe()` 读面 | 探针可见性断言面(hover_probe 返回值、光标形状、格件状态面边框/点迹字段——施工时点在呈现层状态件批合回后,按其改型后投影面口径核对,判据语义零变化)+golden 三张零差异 | 既有:棋盘悬停反馈(三语义光标/目标格边框/路径预览点迹) |
|
||||
| V2 | 断点域拆件 | breakpoint_store.gd 新建;adventure_runner 断点函数族与 6 成员迁出 | 复用 breakpoint_resume_test 全套+save_rng_roundtrip_test+cross_system_flow_test:_feats_breakpoint_roundtrip;新增断言零条;:185 改址(第 14 节申报) | 单元+集成 | AdventureRunner.resume_adventure()/start_adventure() × SaveManagerCore 断点域 | 断点快照往返逐键断言面(27 键冻结——键名/策略/键序零变化) | 既有:断点片段往返与续玩幂等;既有:旧档迁移链与断点续玩零跳号(集成) |
|
||||
|
||||
反向核对:diff 中每个行为改动均有行——本批申报行为改动为零(全部非行为改动=结构整改,判据=零漂移证明)。孤儿断言:无(零新增断言)。
|
||||
|
||||
## 9. 异常分级
|
||||
|
||||
- **L1 自救**:迁移函数编译错、探针调用面改址漏改——就地修复重跑最窄确认。
|
||||
- **L2 记录继续**:实测值与预期区间偏离但同档位——记入实现报告「实现决定记录」。
|
||||
- **L3 停机写报告等用户**:①拆分边界纪律④触发(含 `_r0` 归属认定被实现期证伪);②机检预算互斥——新件实数超第 12 节预算或迁移函数现出超标键=停卡退回写卡段;③golden 对拍差异非零;④S13 键恶化或基线外新键;⑤断言面被下游兜底吸收致判据绑不上。
|
||||
|
||||
## 10. 代拍板白名单
|
||||
|
||||
1. 迁移函数头注指址微调(词表与语义不动)。
|
||||
2. 新件私有 helper 命名微调(职责语义不变)。
|
||||
3. 断言失败消息尾缀〔补件 Vn〕分配与措辞。
|
||||
4. 改址机械改写(preload 顺序、空行排版)。
|
||||
|
||||
## 11. 待裁点
|
||||
|
||||
零待裁点,开工门=U0。(裁决记录:2026-10-29 用户裁——恢复 D2/D4 拆件;D5 五降值键留债、零豁免延伸;`_r0` 留宿主;断点域六成员全迁。)
|
||||
|
||||
## 12. 落位与可复用性预检
|
||||
|
||||
- **board_hover.gd(新增)**:复用面核查——悬停预承诺逻辑现行全在 board_view(11 函数族全仓无第二实现,无既有件可复用);不能并入 TilePalette(瓦片装载)、HeroSprite(英雄演出)、CellUnit(格件绘制)——悬停预承诺与三者是不同变化原因。落点唯一:`game/presentation/views/` 新件,board_view `_init` 建为子件(HeroSprite 挂载先例)。调用路径:只被 board_view 持有与调用,输入经宿主入站口委托,禁反向持宿主引用(注入回调单向)。
|
||||
- **breakpoint_store.gd(新增)**:复用面核查——断点拼盘与读侧策略现行在 adventure_runner(`BREAKPOINT_FIELDS` 登记单源唯一);不能并入 save_manager(存档 IO 原语与冒险断点语义是两个变化原因——SlotStore 拆分已立界)、不能并入 MetaStateStore(元进度数据件)。落点唯一:`game/core/` 新件。调用路径:只被 adventure_runner 调用;宿主经件组装快照后写盘,应用层落盘口不变。
|
||||
- **新增函数**:零——全部为既有函数体逐字搬运。零新增数据件、零新增常量表(`BREAKPOINT_FIELDS` 为迁移非新增)。
|
||||
|
||||
## 13. 实现规范预算(gdstyle 默认阈值对账)
|
||||
|
||||
| 新件 | 公开方法 ≤20 | 类变量 ≤15 | 迁移函数对账 |
|
||||
|---|---|---|---|
|
||||
| board_hover.gd | 预算 6(悬停驱动入口) | 预算 2(`_hover`/`_last_click`)+引用束约 7(cells/minesweeper/diggable 引用+光标写入与 hover_forbidden 注入 Callable)=合计约 9 | 11 函数现行均无超标键(基线无其函数级键);`_apply_hover_visuals` 分支 5 |
|
||||
| breakpoint_store.gd | 预算 8(快照/回填/读侧入口族) | 预算 6(拟拆成员)+引用束约 14(db/rng/主角账三件/curio/stop/bank/loadout)=合计约 20?否——引用束为单成员字典注入,实计=6+1 束+件内散标 ≤15(T0 按实数对账,贴顶禁再增) | `_bp_parts` 现行 49 行/9 局部(:583-630 实测)均在默认阈值内;`_resume_*` 四函数无超标键 |
|
||||
|
||||
存量触面一查:board_view 6 键与 adventure_runner 1 键 T0 读数写明「S13 键较登记值只降不升」预期;`_init` 一律引用束注入防 max-parameters 新键。
|
||||
|
||||
## 14. 测试削弱申报
|
||||
|
||||
1. `breakpoint_resume_test.gd:185`——`AdventureRunnerScript.BREAKPOINT_FIELDS` 直读随件迁改址为 breakpoint_store 常量;判据零变化,仅常量承载文件换代。
|
||||
2. 除此之外禁删断言、禁放宽阈值、禁缩小扫描面、禁把真实入口换成下层直调;未申报的削弱由独立验收审计判红。
|
||||
|
||||
## 15. 独立验收审计
|
||||
|
||||
合并前由未参与实现的会话或子代理执行;报告落 `reports/iter<N>-验收审计-<日期>.md`。审计至少做四件事:逐行核对第 8 节对照表(测试存在、真执行、尾缀可 grep、真实入口未绕过改动点);抽查判据绑定面;检查测试削弱(对照第 14 节申报);核对两行「非行为改动」判定的零漂移证明是否在当轮真实跑批中成立。未过不得合并。
|
||||
|
||||
## 16. MC/数值与 RNG 零触碰声明
|
||||
|
||||
本批零数值改动、零数据表改动、零 RNG 流词表改动——断点回放 restore 同序取号、悬停域无随机。MC 对拍不跑。
|
||||
@@ -0,0 +1,172 @@
|
||||
# 需求卡片——呈现层状态件批
|
||||
|
||||
> **版本状态**:v1.0 定稿——零待裁点(2026-10-29 用户裁:单格两文件案、站桩两文件案、探针计数器留宿主、st/mo 命名、潜伏红随批修复)。
|
||||
> **接收方**:待办清单条目「零豁免五键清偿批——S13 余量五键真修四卡(2026-10-29 登记)」(本卡=四卡中的「呈现层状态件批」一卡,承接 board_cell_unit 类变量 30→10 与 standee_body 类变量 19→10 两键)。
|
||||
> **来源**:两份设计定稿全文。**唯一事实源**:`reports/设计-单格绘制状态件-2026-10-29.md`+`reports/设计-站桩状态件-2026-10-29.md`;`design/engineering/architecture/architecture.md` v1.25「模块归属·呈现层」表 cell_base_layer/cell_mark_overlay 行(:169)与 standee_vitals/standee_motion 行(:170)。
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
这批做什么:把两个呈现层宿主的内部状态件沿职责缝拆成四个独立文件类——单格 `board_cell_unit.gd` 的 `_CellPaintState`(27 成员)按绘制层域轴拆 `cell_base_layer.gd`(12 成员)+`cell_mark_overlay.gd`(13 成员),宿主 `_draw` 退六步时序器、类变量 30→10;站桩 `standee_body.gd` 的 `_StandeeState`(真实 25 成员——基线 19 是 gdstyle 计数截断的欠估读数)按「身份命值/资产演出」缝拆 `standee_vitals.gd`(12 成员)+`standee_motion.gd`(11 成员),三个演出探针计数器留宿主、类变量 19→10。宿主实例命名:单格两件 `base`/`face`;站桩沿用 `st`(指 vitals)+新增 `mo`。附带处置一处潜伏红:ui_input_probe 四处绕过状态件直读格件成员的断言疑似已被迭代 41 状态件化打断,T0 实跑定谳,确红则随批修复。
|
||||
|
||||
什么状态算完:
|
||||
|
||||
1. 四新件在库、两宿主瘦身到位、六个 gdstyle 键账达预期(board_cell_unit 10/standee_body 10——较登记值 30/19 只降不升;四新件 12/13/12/11 全部阈值内零新键)。
|
||||
2. 行为零变化:棋盘 golden 三张(L1 dungeon/L2 underdark/L3 deep_underdark)对拍差异 0.00%;探针冻结成员(glyph/fog_state/plate/glyph_color)与站桩演出时序、三条源码锚逐字不动。
|
||||
3. 潜伏红定谳结论记实现报告;确红则四处改址落地、probe_gate 全绿闭环。
|
||||
4. 批末代码域闸全绿;实现报告与反哺点清单写齐方算收口。
|
||||
|
||||
## 2. 设计事实源
|
||||
|
||||
两份设计定稿(2026-10-29 设计闭合,待办清单条目凭据与本节一致):单格篇 §4 拆分定案(两件案 A2、成员总账 10/12/13、写入路径对账表 §5.1、六步时序器 §6、键账预期 §7)、§1.2 gdstyle 截断缺陷与 §1.3 潜伏红发现、§1.4 探针直读面全清单;站桩篇 §3 方案 C(两独立文件+计数器留宿主)、§4 外部写入方零改动清单、§5 键账预期、§6 行为零变化六点。architecture.md v1.25 两行在册(呈现层表 :169-:170——职责语句、成员数、宿主 30→10/19→10)与「gdstyle 计数截断缺陷登记」节。
|
||||
|
||||
## 3. 现状事实(2026-10-29 主区实查;行号为迭代 42 合回前盘面——T0 必须在迭代 42 合回后按当轮 master 重锚)
|
||||
|
||||
**编队注记**:本卡与迭代 42 有 board_view 触面耦合——迭代 42(在飞,roadmap 迭代 42 行「进行中」)尾波清偿批 T1 把 `_paint_cell` 拆五段(`_paint_cell_base/_ink/_facade/_overlays/_fog`,段间只经 u.st/glyph/digit_col 传值)并抽 `_build_cell_unit`(:246-262),改变 u.st 写入面的函数分布结构(写入语句从单函数分散进段函数),写入路径形态 u.st.X 本身不变。**本卡 T0 必须在迭代 42 合回后执行**;本节行号按当前盘面实查,届时 board_view 全部写入点行号漂移、以 T0 重锚为准。反向编队义务:尾波补件批(board_hover)已裁「u.st 写入面改型后 hover 拆件在新面上施工」——本批先于其 board_hover 半边合回。另:本卡与组合根注册面批共享 ui_input_probe.gd 触面(该批改 main.X 地址面、本批改四处 u.face.* 读面,互不覆盖但同文件)——同代编排时禁并行、先后皆可,编入前置声明互指。
|
||||
|
||||
- **键账**:`tools/gdstyle_baseline.txt` :16 `board_cell_unit.gd|quality/max-class-variables = 30`、:23 `standee_body.gd|quality/max-class-variables = 19`。源码实查:board_cell_unit.gd 全文件 33 个类级 var(宿主 6+`_CellPaintState` 27,:26-122 内嵌类/:125-143 宿主);standee_body.gd 全文件 31 个(宿主 6+`_StandeeState` 25,:23-59 内嵌类/:62-68 宿主)。登记值 30/19 均为 gdstyle 对 inner class「首个带行尾注释属性截断」的欠估(architecture v1.25 已登记该工具缺陷;board_view.gd 无内嵌类、32 逐一全计——平面口径预测即实测)。
|
||||
- **单格写入方**:唯一写方文件 board_view.gd。写入点实查——set_world_font:185(font)、set_cell_area:204(edge)、rebuild:250/251/253/260(cell/edge/bevel/font)、悬停面 :512-534(hl_visible/hl_color 五组写+一清)、路径预览 :549/:554(dot_visible)、`_paint_cell` :601-738(tex_seal:614/618、tex_base:665、bg_sb:666、glyph:667、glyph_color:668/674、plate:675、outline_sides:676/700、facade_south:677/690、proj_band:678/704、tex_facade:679/709、facade_strip:680/708、treasure_mark:713、badge_glyph:719/726、mutation_mark:723/725、glow_group:727、fog_state:734/736、removed_dim:737、终写 queue_redraw:738)、接触带 :780/:787/:804/:805/:810/:816、glow 同步 :768、cell_rect_probe 读 :891(u.st.edge)。
|
||||
- **站桩外部触面**:唯一写状态的外部方 battle_stage_view——slot_row :140/:265、box :198/:208、font :232/:235、set_portrait_texture/register_hero_state :132-138、set_hero_state :313/:316/:388、演出三方法 :333-336;hud_presenter :77/:78/:137/:162/:163(set_hero/set_effects/set_effects_cleared_feedback);fx_probe 对 box 直写三处。测试直读 standee_fx_sweep_test.gd:103(`s1._intent_charge`);源码锚 theme_projection_test.gd:678-683(GOLD_BRIGHT 顺位墨/HERO_BLUE_BRIGHT 与 GOLD_BRIGHT 护甲墨/`_intent_charge = pid in CHARGE_SKILL_IDS` 三条 contains 断言)。
|
||||
- **潜伏红(T0 定谳)**:ui_input_probe.gd 四处绕过 st 直读格件成员——:234-235(case① `u1.hl_visible`/`u1.hl_color`)、:243-244(case② `.hl_color`)、:250(case③ `.dot_visible`)、:374-379(case⑭ `.mutation_mark`)。这四个成员迭代 41 已迁入内嵌类 `_CellPaintState`,宿主 Node2D 上不存在同名属性,外部读预期运行时「Invalid get index」错误。时间线:探针末次全绿 2026-10-28 05:03 早于状态件合入 2026-10-29 01:37,合入后未跑过。设计文档同篇已含改址方案(u.face.*)。
|
||||
- **探针冻结面(零改动义务)**:ui_input_probe.gd:271/:363(u.glyph)、:400-:492(u.fog_state case⑮族);player_copy_sweep_test.gd:138-140(u.plate/u.glyph_color wa8)。plate 绘制侧零消费(禁删禁接线——接线即行为变化)。
|
||||
- **演出探针计数器**:standee_body.gd:57-59(_death_shards/_hit_sparks/_flash_count);唯一写入方宿主函数 :275/:315/:336,唯一读方 fx_probe() :301。
|
||||
- **文件体量**:board_cell_unit.gd 423 行(迭代 41 已拆函数级键、本设计只解决类变量键;拆后宿主约 150 行);standee_body.gd 531 行。
|
||||
|
||||
## 4. 设计契约(违反即返工的红线条款)
|
||||
|
||||
- 🔴 **行为零变化**:绘制调用序与层序零变化——宿主 `_draw` 六步时序器与现行四函数调用树逐命令等价(设计文档单格篇 §6 四点论证:层间序/件内逐字搬运/接触带回退补画序整体保形/浮点推导式零改动);接触带「平色回退+微光并发的英雄格补画」重复绘制路径原样保形;setter 多写多触发序不变(facade_south/badge_glyph/mutation_mark 双写点);站桩六点(tween 路径串、三态机早退序、`_hp_flash_tw` 回色读 `_dead` 同拍、源码锚逐字、成员初始化时序、计数器纯易位)=站桩篇 §6。
|
||||
- 🔴 **golden 三张零差异**:render_gate 棋盘 golden(L1 dungeon/L2 underdark/L3 deep_underdark)对拍差异 0.00%;非零即停机呈报,禁换锚、禁重制基线。
|
||||
- 🔴 **冻结面逐字**:探针冻结成员 glyph/fog_state/plate/glyph_color 宿主保留、名称路径零变化;站桩三条源码锚所在函数留宿主且锚行逐字;battle_stage_view 一行不改(写入面零改动清单=站桩篇 §4)。
|
||||
- 🔴 **拆分边界纪律**(判据权威=code-conventions §1.1,卡内执行条款;实现报告逐件一行职责语句):①拆出单元须有可陈述职责语句与单一变化原因——四件职责语句与宿主保留面语句照设计文档 §4.2/§4.3/§4.4 与站桩篇 §3 逐字承载(基座层绘制域/标识叠加绘制域/身份命值唯一账面/资产挂点与一次性演出;单格宿主=被动绘制壳+迷雾域+微光子件生命周期);②集体身份——命不出名字的打包=凑计数袋,禁;③「过阈值」只作发现信号,拆分动机是职责轴(迭代 41 函数级已沿同一条绘制层域轴,本批升到类级);④拆不出内聚单元→停卡呈报;⑤禁沿阈值轴拆。
|
||||
- 🔴 **禁为机检文本保留无效成员**:禁止为迎合机检消息文本(含计数)保留或新增无效成员/别名;机检键与卡片契约互斥=实现段停卡呈报,不自造第三条路。
|
||||
- 🔴 **gdstyle 截断缺陷声明**:本卡不依赖任何解析行为——四新文件与两宿主全部平面口径(无内嵌类),实数即闸读数;基线登记 30/19 属截断欠估,禁任何利用截断口径的降数手法(重排成员顺序/挪 setter 位置/删行尾注释),禁把 `_portrait_tex` 这类承重槽位当削减目标凑数。
|
||||
- 🔴 **潜伏红处置纪律**:T0 一次 ui_input_probe 实跑定谳——确红=已申报的存量红承接,随批修复(T3 四处改址 u.face.*,断言条件与期望值零变化);禁静默放过、禁在实现报告外私记了结。
|
||||
|
||||
## 5. 范围边界
|
||||
|
||||
做什么:第 3 节两拆件项(单格两域件+宿主上收+board_view 写入面改址;站桩两状态件+宿主转调壳)、潜伏红定谳与四处改址、键账对账收口。
|
||||
|
||||
不做什么:迭代 42 在飞范围零触碰(_paint_cell 拆五段、_build_cell_unit、BoardInstaller、商店委托壳);board_hover/breakpoint_store(尾波补件批承接,且其 board_hover 半边待本批合回后施工);main.gd/battle_orchestrator/tune_sim 其余三键(零豁免五键各卡承接);`_portrait_tex` 冗余归一(站桩篇 §9-3 留债册);基线收账(各批合回后用户发令一次人工 `--refresh --force`,本批不刷新基线)。
|
||||
|
||||
## 6. 关联文档同步面
|
||||
|
||||
| 文档 | 关联点 | 同步义务 |
|
||||
|---|---|---|
|
||||
| design/engineering/architecture/architecture.md | 呈现层表 cell_base_layer/cell_mark_overlay 行与 standee_vitals/standee_motion 行(建件后「实现批建件」改现状登记);「gdstyle 计数截断缺陷登记」节的欠估数字(30/33、19/31——收账归后续人工 refresh 批) | 设计权威文档——实现批禁直改;逐条列进 `reports/iter<N>-反哺点-<日期>.md`,用户裁决后归文档批落文 |
|
||||
| game/tests/README.md | 「棋盘悬停反馈(三语义光标/目标格边框/路径预览点迹)」行——真实入口(ui_input_probe 合成鼠标事件→BoardView._gui_input();读面 hover_probe())与代表用例(ui_input_probe.gd:_ready)预计零变化,批末核对;「地形瓦片套与格面数字可读」「站桩敌人呈现与结算演出落点」「未开格类型微光」「玩家面文案与危险格格面字形」各行代表用例列核对(本批零新增能力、复用既有载体,预计零改动) | 机械面文档——实现批禁写;批末收尾核对表上名字与实际落地一致(改名则回表) |
|
||||
| design/gdd/ | 无关联文档——结构整改不改游戏规则与玩家可见行为 | 无修订预期;契约句被触碰=停卡呈报走反哺点通道 |
|
||||
|
||||
## 7. 文件结构图(卡前)
|
||||
|
||||
| 文件 | 新增/修改 | 职责 | 行为属性 |
|
||||
|---|---|---|---|
|
||||
| game/presentation/views/cell_base_layer.gd | 新增 | 单格基座层绘制域件:12 成员+九绘制函数逐字搬运+九个 D/E 档常量随迁+公开入口 draw_base | 非行为改动(V1) |
|
||||
| game/presentation/views/cell_mark_overlay.gd | 新增 | 单格标识与叠加层绘制域件:13 成员+六函数段随迁+draw_centered_text 单点化+两绘制入口 | 非行为改动(V2) |
|
||||
| game/presentation/views/standee_vitals.gd | 新增 | 站桩身份与命值态件:12 成员+apply_hp(原 _set_hp 整体搬移)+hp_value setter 逐字 | 非行为改动(V3) |
|
||||
| game/presentation/views/standee_motion.gd | 新增 | 站桩资产与演出态件:11 成员+六迁入函数(两处改形点见 T2) | 非行为改动(V3) |
|
||||
| game/presentation/views/board_cell_unit.gd | 修改 | 宿主瘦身:类变量 33→10(edge/cell/glow_group 上收+base/face 两实例)、_draw 退六步时序器、雾/glow/记忆态留宿主、头注改写(≤8 行) | 非行为改动(V1/V2) |
|
||||
| game/presentation/views/board_view.gd | 修改 | 写入面改址约 40 处(u.st.X→u.base./u.face./u.edge/u.glow_group/u.cell,全清单=设计文档单格篇 §5.1/§5.2 对账表;行号 T0 重锚)+cell_rect_probe 一处 | 非行为改动(V1/V2) |
|
||||
| game/presentation/views/standee_body.gd | 修改 | 宿主改造:类变量 31→10(五冻结 var+st+mo+三计数器)、同名转调壳、tween 路径串改指、源码锚行逐字不动 | 非行为改动(V3) |
|
||||
| game/probe/ui_input_probe.gd | 修改 | 四处直读改址 u.face.*(T3,:234-235/:243-244/:250/:374-379) | 非行为改动(V4——判据零变化;T0 确红时兼具存量红修复身份) |
|
||||
|
||||
零新增数据件、零新增常量表(九常量为迁移非新增)、零新增测试件(全部复用既有断言面)。行为改动核对:本批申报行为改动为零——全部改动为逐字搬运、换参形与读路径改址;判据=零漂移证明(golden 零差异+既有断言面全绿+源码锚逐字)。
|
||||
|
||||
## 8. 任务卡 T0..T4
|
||||
|
||||
**T0 重锚与潜伏红定谳(0.25–0.5 工作日)**
|
||||
|
||||
- [ ] 前置确认:迭代 42 已合回 master(`_paint_cell` 五段在盘)——未合回即停,T0 不开工(编队注记)
|
||||
- [ ] 以当轮 master 重测六个键账读数(board_cell_unit 33 声明/30 闸账、standee_body 31 声明/19 闸账——截断口径双读数对照)与第 3 节全部 file:line;board_view 写入点按五段新分布逐点重锚(路径形态核对仍为 u.st.X)、漂移处就地改卡并记录;对不上即停卡呈报
|
||||
- [ ] ui_input_probe 一次实跑定谳潜伏红:红=确证设计文档单格篇 §1.3;绿=证伪设计前提(L3 停机呈报,见第 10 节)——定谳结果记实现报告
|
||||
- [ ] 复核迁移函数零超标键:`tools/gdstyle_baseline.txt` 无 board_cell_unit/standee_body 任何函数级键(实查确认)——九+六函数与六搬移函数逐字/换参搬运零新键
|
||||
|
||||
**T1 单格两域件建件与迁移(1.5–2.5 工作日)**
|
||||
|
||||
- [ ] 建 `game/presentation/views/cell_base_layer.gd`:extends RefCounted、无 class_name、`_init(owner: Node2D)`;12 成员+四 setter 体逐字;九函数(_draw_base_layer/_draw_outline_sides/_draw_south_facade/_draw_north_projection/_draw_e_facade/_draw_contact_or_fallback/_draw_contact_bands/_draw_contact_corner/_draw_bevel)逐字搬运,三处机械改写=`st.X`→裸成员名、`draw_X(...)`→`canvas.draw_X(...)`、`st.edge`→`rect.size.x`;公开入口 `draw_base(canvas: CanvasItem, rect: Rect2)`;九常量随迁(FACADE_HIGHLIGHT_PX/FACADE_NEAR_FRAC/FACADE_FAR_FRAC/FACADE_NEAR_COL/FACADE_FAR_COL/PROJECTION_NEAR_COL/PROJECTION_MID_COL/PROJECTION_EDGE_COL/E_FACADE_FRAC——board_cell_unit.gd:12-23,UiKit.E_FACADE_FOOT_COL 不动)
|
||||
- [ ] 建 `game/presentation/views/cell_mark_overlay.gd`:同形态;13 成员+八 setter 体逐字(含 badge_glyph 的 `_owner._glow_layer` mask 回引);六函数段随迁(_draw_mutation_marks/_draw_glyph_layer/_draw_digit_plate/_draw_glyph/_draw_badge+_draw_overlay_layers 的 dot/hl/removed 三段);公开入口 `draw_marks`/`draw_glyph_layer(canvas, rect, glyph, glyph_color)`(4 参)/`draw_overlay_under`/`draw_removed_dim`/`draw_centered_text(canvas, rect, text, color, font_size)`(5 参,文字渲染单点化)
|
||||
- [ ] 宿主瘦身:board_cell_unit.gd——`base`/`face` 两实例于 `_init` 自建(preload 常量 `_BASE_LAYER`/`_MARK_OVERLAY`,设计文档 §4.5);edge/cell/glow_group 上收宿主(setter 体改直调自有面:edge 的 glow setup+queue_redraw、glow_group 守卫调 `_sync_glow_layer()`);glyph/glyph_color/plate/fog_state/_glow_layer 原位;`_draw` 改六步时序器(base.draw_base→face.draw_marks→face.draw_glyph_layer→face.draw_overlay_under→`_draw_fog_layer` 原位→face.draw_removed_dim,设计文档 §6 逐字);`_sync_glow_layer`/`_draw_fog_memory` 改址(§5.2——记忆态墨数字改调 face.draw_centered_text,同公式同字号);头注改写(两件句+冻结清单+「hl_color/hl_visible/dot_visible/mutation_mark 探针读 u.face.*」句,≤8 行)
|
||||
- [ ] board_view 写入面逐点对账改址:按设计文档单格篇 §5.1 对账表每处核对改后形态(T0 重锚行号为准,约 40 处)——u.base.bg_sb/tex_base/outline_sides(assign 保引用语义)/facade_south/proj_band/tex_facade/facade_strip/contact_bands/contact_corners/contact_col/bevel;u.face.badge_glyph/dot_visible/hl_visible/hl_color/tex_seal/treasure_mark/mutation_mark/removed_dim/font/tex_mutation/tex_glyph/tex_badge;u.edge/u.cell/u.glow_group;u.glyph/u.glyph_color/u.plate/u.fog_state 与终写 u.queue_redraw() 不动;cell_rect_probe `u.st.edge`→`u.edge`
|
||||
- [ ] 孤立验证:`tools/render_gate.sh` golden 三张差异 0.00%(非零即 L3 停机);`--script res://tests/run_all.gd -- --only=player_copy,theme_projection,type_glow,terrain` 全绿;`python tools/run_smoke.py`。probe_gate 各段本卡内暂不计绿——ui_input_probe 段在 T3 改址前处于 T0 已定谳态(存量红或改址等待),T3 闭环
|
||||
|
||||
**T2 站桩两状态件建件与迁移(0.5–1 工作日)**
|
||||
|
||||
- [ ] 建 `game/presentation/views/standee_vitals.gd`:RefCounted、无 class_name;12 成员(_owner/_kind/_display_name/_enemy_id/_armor/_order/_dead/_hp_max/_hp_cur/hp_value/_hp_tween/_hp_flash_tw);`apply_hp(hp)`=原 `_set_hp` 整体搬移(clamp、重启 `_hp_tween`、tween 写 hp_value——路径串 `"st.hp_value"` 零改);`hp_value` setter 逐字(clamp+`_owner.queue_redraw()`);`_hp_flash_tw` 归此件(flash_hit 回色分支读 `_dead` 同域)
|
||||
- [ ] 建 `game/presentation/views/standee_motion.gd`:RefCounted、无 class_name;11 成员(_owner/_portrait_sprite/_portrait_tex/_hero_tex/_hero_state/_state_revert_tw/_intent_glyph/_intent_col/_intent_visible/_intent_scale/_glyph_rot);六迁入函数——`set_portrait_texture(tex, flip, box)`(box 由宿主传入)、`register_hero_state`、`apply_hero_state(state, is_hero)`(原 set_hero_state,唯一改形=`st._kind != "hero"` 早退改参判 `is_hero`,三连早退条件序逐字)、`reset_state()`(原 `_revive` 内「置 RESET 强制绕同态早退」两拍封装)、`play_intent_motion(charge)`(`_intent_charge` 改参传入;tween 路径串改 `"mo._intent_scale"`/`"mo._glyph_rot"`)、`state_probe()`
|
||||
- [ ] 宿主改造:standee_body.gd——`st` 名保留改指 vitals、新增 `mo`;三计数器留宿主(:57-59 原位);同名转调壳(set_portrait_texture/register_hero_state/set_hero_state 三入口 1–2 行转调,签名外形零变);`_draw` 全族与几何函数留宿主、成员前缀改指(st.→mo. 仅资产演出域成员);六个 probe/display_name/enemy_id/is_dead 出口外形零变体内改指(fx_probe 改读宿主计数器);源码锚所在三函数(_draw_hp_bar/_draw_armor_name_line/set_pending)留宿主且 :678-683 锚行逐字不动;`_intent_charge` 与五冻结 var 原位
|
||||
- [ ] battle_stage_view 写入面对账(站桩篇 §4 清单逐点):结论=零改动——slot_row/box/font 直写原位、三同名转调入口承接、演出三方法原位;hud_presenter :77/:78/:137/:162/:163 零改动;实机核对一遍
|
||||
- [ ] 孤立验证:`--script res://tests/run_all.gd -- --only=standee_fx_sweep,theme_projection` 全绿;孤立验证同 T1 口径(probe_gate 推迟 T3 闭环)
|
||||
|
||||
**T3 潜伏红处置(0.25–0.5 工作日)**
|
||||
|
||||
- [ ] ui_input_probe.gd 四处改址::234-235→`u1.face.hl_visible`/`u1.face.hl_color`、:243-244→`.face.hl_color`、:250→`.face.dot_visible`、:374-379→`.face.mutation_mark`——断言条件与期望值零变化,只改读路径
|
||||
- [ ] 孤立验证(本卡闭环点):`tools/probe_gate.sh --click --full` 全绿——ui_input_probe 恢复绿;若 T0 定谳为红,本步同时即存量红修复闭环;`tools/render_gate.sh` golden 三张复跑一次仍 0.00%
|
||||
|
||||
**T4 键账对账与收口(0.5 工作日)**
|
||||
|
||||
- [ ] 批末代码域闸全绿(`tools/run_all_gates.sh --code`——三件保险恒跑+本卡申报套件族+探针+渲染+静态)
|
||||
- [ ] 六文件键账对账:board_cell_unit 10/cell_base_layer 12/cell_mark_overlay 13/standee_body 10/standee_vitals 12/standee_motion 11(平面口径实测);两存量键 30→10、19→10「较登记值只降不升」达成;基线不随批刷新(收账归用户发令人工 refresh)
|
||||
- [ ] 产出物落位卡:`reports/iter<N>-实现报告-<日期>.md`(各卡状态+潜伏红定谳结论+实现决定记录)与 `reports/iter<N>-反哺点-<日期>.md`(第 6 节所列每条有落点)写齐方算收口
|
||||
|
||||
合计约 3–5 工作日。切分预案:T1 超软盒时拆 T1a(基座件+宿主上收)/T1b(叠加件+board_view 改址)各 0.75–1.25 工作日。回归措辞:里程碑步(T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套(本批零新增测试)。
|
||||
|
||||
## 9. 验证闸——改动—验收对照表
|
||||
|
||||
域口径:本批改动全为 `game/` 下非 .md 行为载体——批末跑代码域闸(重闸按域选档);总判据=每行改动以「既有断言面全绿+golden 零差异」证明零行为漂移。**静态键账判据按 test-conventions §8.4 出口在本段申报观测面局限、不入对照表**:S13 六文件键账(10/12/13/10/12/11)与两存量键只降不升(30→10、19→10)以 static_scan S13 回执为判据(可 grep 定位)——键清偿是结构判据非运行期断言,故不出现在下表。
|
||||
|
||||
| 行 | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| V1 | 单格基座层域件 | cell_base_layer.gd 新建(12 成员+九函数+九常量);board_cell_unit.gd 宿主上收 edge/cell/glow_group+六步时序器;board_view.gd 基座域写入点改址(对账表 §5.1 基座行) | render_gate 棋盘 golden 三张(board_L1/L2/L3)+board_shot_probe/type_glow_shot_probe 取证;新增断言零条 | 探针+golden | BoardView.rebuild()→refresh() 真实场景帧(board_shot_probe) | golden 逐像素容差比对(差 ≤16/changed ≤2%)差异 0.00%=绘制命令流逐位;微光子件生命周期取证(glow_group setter 直调时序零漂移) | 既有:地形瓦片套与格面数字可读;既有:未开格类型微光(8 邻作用集/五组色相/零玩法写入) |
|
||||
| V2 | 单格标识叠加域件+冻结面保留 | cell_mark_overlay.gd 新建(13 成员+六函数段+draw_centered_text);board_cell_unit.gd 四冻结成员原位;board_view.gd 标识域写入点改址+cell_rect_probe 一处 | 复用 player_copy_sweep_test.gd:_sweep_board_glyph+wa8(:138-140 plate/glyph_color 直读零改动);ui_input_probe case④b/⑪/⑮(glyph/fog_state 冻结读面);run_all 02 闸选跑+render_gate golden;新增断言零条 | 单元+探针+golden | BoardView.rebuild()→refresh()(player_copy 夹具真实构建);ui_input_probe 合成鼠标事件 | u.plate/u.glyph_color/u.glyph/u.fog_state 直读断言零改动全绿;golden 三张零差异(雾层原位夹在 hl 与 removed 之间) | 既有:玩家面文案与危险格格面字形;既有:地形瓦片套与格面数字可读 |
|
||||
| V3 | 站桩两状态件 | standee_vitals.gd/standee_motion.gd 新建;standee_body.gd 宿主 10 成员+转调壳+tween 路径串改指;battle_stage_view 写入面零改动 | 复用 standee_fx_sweep_test 全套(:103 `_intent_charge` 直读、fx_probe().flash_count、enemy_id 解析)+theme_projection_test 三条源码锚(:678-683 逐字)+probe_gate --full 段(fx_probe/ui_probe:碎裂 5/火花 6/闪白计数/三态切换/意图三档/name_line/portrait/has_world_hp_bar/slot_row)+ui_click_probe tooltip;新增断言零条 | 单元+探针 | StandeeBody 公开方法面(set_data/set_hero/set_pending/mark_dead/flash_hit)与 battle_stage_view.on_step_row_fx 演出链;探针场景真实实例化 | fx_probe()/intent_probe()/hero_state_probe() 出口返回逐键;源码锚 contains 断言逐字命中;tween 属性路径串("st.hp_value"/"mo._intent_scale"/"mo._glyph_rot")由意图弹入与三态断言兜底 | 既有:站桩敌人呈现与结算演出落点;既有:UI 全局主题与按钮五态(含对比度锚) |
|
||||
| V4 | 潜伏红处置与探针改址 | ui_input_probe.gd:234-235/:243-244/:250/:374-379 四处直读改址 u.face.*(判据零变化;T0 确红时兼具存量红修复) | ui_input_probe 全套断言改址后执行且绿(case①②③⑭);probe_gate --click --full 全绿 | 探针 | ui_input_probe 合成鼠标事件→BoardView._gui_input() | 四处断言执行且绿(悬停金框/禁入红框/路径点迹/变异角标,读路径 u.face.*);probe_gate 三硬闸全过=存量红闭环 | 既有:棋盘悬停反馈(三语义光标/目标格边框/路径预览点迹) |
|
||||
|
||||
反向核对:diff 中每个改动均有行——本批申报行为改动为零(结构整改,判据=零漂移证明),V1–V4 四行覆盖全部八个文件行。孤儿断言:无(零新增断言)。
|
||||
|
||||
## 10. 异常分级
|
||||
|
||||
- **L1 自救**:迁移函数编译错、改址漏改、preload 常量名笔误——就地修复重跑最窄确认。
|
||||
- **L2 记录继续**:实测行号与第 3 节偏离但路径形态一致(T0 重锚记录);探针段实测时长同量级漂移。
|
||||
- **L3 停机写报告等用户**:①机检预算互斥——新件实数超第 14 节预算或迁移函数现出超标键=上游缺陷停卡退回写卡段;②golden 对拍差异非零(禁换锚禁重制基线);③潜伏红证伪设计前提——T0 实跑 ui_input_probe 现状绿,即设计文档单格篇 §1.3 的 GDScript 取索引语义判断被证伪(改址四处义务不变,等用户裁决后继续);④S13 键恶化或基线外新键;⑤拆分边界纪律④触发(按职责轴拆不出内聚单元);⑥断言面被下游兜底吸收致判据绑不上(test-conventions §8.4 出口呈报)。
|
||||
|
||||
## 11. 代拍板白名单
|
||||
|
||||
1. 迁移函数与新件头注指址微调(职责语句、冻结清单句与语义不动)。
|
||||
2. 新件私有 helper 命名微调(职责语义不变;公开入口名按第 8 节逐字)。
|
||||
3. 改址机械改写(preload 常量顺序、空行排版、注释随迁改写)。
|
||||
4. 断言失败消息尾缀〔状态件 Vn〕分配与措辞。
|
||||
5. T0 重锚产生的行号漂移卡面注记更新(不改判据与改后形态)。
|
||||
|
||||
## 12. 待裁点
|
||||
|
||||
零待裁点,开工门=U0。(裁决记录:2026-10-29 用户裁——单格两文件案〔淘汰整体一件 A3 与成员削减路 B〕;站桩两文件案+三个演出探针计数器留宿主〔淘汰原地 −4 案〕;实例命名 st 沿用/mo;潜伏红随批修复〔弃「先最小工程批改 u.st.* 再二次改址」时序〕;cell 成员保留〔宿主 10 含 cell——弃删除倾向〕;gdstyle 截断口径登记已由 architecture v1.25 落文收口。)
|
||||
|
||||
## 13. 落位与可复用性预检
|
||||
|
||||
- **cell_base_layer.gd(新增)**:复用面核查——基座层绘制现行全在 board_cell_unit 内嵌类+宿主九函数(全仓唯一实现,无既有件可复用);不能并入 TilePalette(瓦片装载与查表件、架构表明载零绘制面——职责互斥)、不能并入 BoardWorld(世界根/材质挂点)、不能并入 CellUnit 本体的字形迷雾域(变化原因不同)。落点唯一:`game/presentation/views/` 新件,board_cell_unit `_init` 自建持有(每格 Node2D+两 RefCounted,与现状同量级;件内自建不触发 allocation-in-loop 新键——构建器函数体不在循环体内)。交互路径:宿主持有两件引用;件→宿主仅 `_owner.queue_redraw()`/glow mask 回引(与现状 inner class 同形);宿主迷雾记忆态读 `base.tex_base` 公开成员单向(成文于宿主头注)。
|
||||
- **cell_mark_overlay.gd(新增)**:同上排除;迷雾留宿主是三域中唯一不产生跨件回引的落点(设计文档 §4.4——雾夹在两件入口之间、读件 A 纹理与件 B 字体渲染);`draw_centered_text` 单点化供宿主复用(零复制)。
|
||||
- **standee_vitals.gd/standee_motion.gd(新增)**:复用面核查——25 成员现行全在 `_StandeeState`(全仓唯一);不能并入 battle_stage_view(壳层视图,站桩本体是世界件)、不能并入 StatusSlotRow(壳层伴随件)。落点唯一:`game/presentation/views/` 新件,standee_body 持有 st/mo;外部仍只经宿主方法与五冻结 var(box/font/slot_row/has_world_hp_bar/_intent_charge 原位),零新增外部直访面;`_owner` 回引同形、禁反向引用。
|
||||
- **四新件对既有周边件逐一排除**(TilePalette/HeroSprite/CellUnit/BoardWorld,架构文档呈现层表在册件):TilePalette=瓦片装载与查表件、架构表明载零绘制面——四件都不并入;HeroSprite=英雄精灵演出件(落位/位移/帧闪)——与四件变化原因不同;CellUnit 本体(board_cell_unit 宿主)=两格件的持有壳而非合并对象(拆分方向是自宿主出、非并入宿主);BoardWorld=棋盘 Node2D 世界根(材质挂点)——零绘制入参承载。站桩两件另排除 battle_stage_view(壳层视图)与 StatusSlotRow(壳层伴随件)。
|
||||
- **新增函数清单**:apply_hp/set_portrait_texture(3 参形)/apply_hero_state(is_hero 参形)/reset_state/play_intent_motion(charge 参形)/state_probe/draw_base/draw_marks/draw_glyph_layer/draw_overlay_under/draw_removed_dim/draw_centered_text——全部为既有函数体整体搬移或既有函数换参形与改名入口,无新逻辑。新增前已 grep 同名标识符:`apply_hero_state`/`reset_state`/`state_probe`/`draw_base` 等盘上无第二处。
|
||||
|
||||
## 14. 实现规范预算(gdstyle 默认阈值对账)
|
||||
|
||||
| 新件 | 公开方法 ≤20 | 类变量 ≤15 | 迁移函数对账 |
|
||||
|---|---|---|---|
|
||||
| cell_base_layer.gd | 预算 5(draw_base+4 setter) | 12(设计文档 §4.1 实数) | 九函数逐字搬运——基线无其函数级键(T0 实查)、行数/分支/局部/返回不变=零新键 |
|
||||
| cell_mark_overlay.gd | 预算 13(5 绘制入口+8 setter) | 13(同上) | 六函数段同上;draw_glyph_layer 4 参、draw_centered_text 5 参(max-parameters 默认 5=合规上限内) |
|
||||
| standee_vitals.gd | 预算 1(apply_hp)+hp_value setter | 12(设计文档 §5 实数) | apply_hp 整体搬移零键(原 _set_hp 现役无超标键) |
|
||||
| standee_motion.gd | 预算 6(六迁入函数)+2 属性 setter | 11(同上) | 六搬移函数逐字/换参——最大者 apply_hero_state 4 参数 4 分支全在原值内;宿主转调壳 1–2 行零键 |
|
||||
|
||||
存量触面一查:board_cell_unit 键 30→10、standee_body 键 19→10——T0 写明「S13 键较登记值只降不升」预期与达成手段(成员迁出后实数即证);board_view 六键零触碰(改址不动成员数与函数面,32 留债冻结)。宿主 `_init` 一律单参构造注入,防 max-parameters 新键。
|
||||
|
||||
## 15. 测试削弱申报
|
||||
|
||||
1. ui_input_probe.gd 四处直读改址(T3/V4)——断言条件与期望值零变化,仅读路径 u.X→u.face.X;若 T0 确红,同处兼具存量红修复(恢复断言效力)。
|
||||
2. 除此之外禁删断言、禁放宽阈值、禁缩小扫描面、禁把真实入口换成下层直调;golden 三张基线禁重制;未申报的削弱由独立验收审计判红。
|
||||
|
||||
## 16. 独立验收审计
|
||||
|
||||
合并前由未参与实现的会话或子代理执行;报告落 `reports/iter<N>-验收审计-<日期>.md`。审计至少做四件事:逐行核对第 9 节对照表(测试存在、真执行、尾缀可 grep、真实入口未绕过改动点);抽查判据绑定面(golden 零差异在当轮真实跑批成立、源码锚逐字);检查测试削弱(对照第 15 节申报);核对全部行「非行为改动」的零漂移证明。未过不得合并。
|
||||
|
||||
## 17. MC/数值与 RNG 零触碰声明
|
||||
|
||||
本批零数值改动、零数据表改动、零 RNG 流词表改动;站桩演出与呼吸微光时长全经 UiKit.motion 现值、零漂移。MC 对拍不跑。
|
||||
@@ -0,0 +1,208 @@
|
||||
# 需求卡片——战斗编排归约批(battle_orchestrator 类变量 38→15)
|
||||
|
||||
> **版本状态**:v1.0 定稿——零待裁点(2026-10-29 用户裁:RoundCycle/BattleFacts 两件形态、encounter 归 BattleFacts、attune 改判、treasure_inventory 改址追认、完美账写口升级可裁量)。
|
||||
> **接收方**:待办清单条目「战斗域结构深拆批——效果发射端口+宿主瘦身+掷格/受理分件(2026-10-27 登记,来源=批次移交)」——本卡承接其中 battle_orchestrator 瘦身面(architecture 轴丁);该条目的效果发射端口与 reward_economy 分件两子项不在本卡。
|
||||
> **来源**:`reports/设计-战斗编排类变量归约-2026-10-29.md`(设计讨论段定稿,五待裁点 2026-10-29 用户裁全闭合)。**唯一事实源**:该设计文档全文 + `design/engineering/architecture/architecture.md` v1.25「战斗编排域拆件定稿」节轴丁与「模块归属·功能层」RoundCycle/BattleFacts 两行。
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
这批做什么:把战斗结算编排宿主 `game/core/battle_orchestrator.gd` 的 38 个类变量收敛到 15(=gdstyle 阈值,合规)。手段=按变化原因拆两枚新件收编 22 个成员——**RoundCycle**(轮循环驱动件:五段段件持有、段序执行、结算重入门闸、开轮摇号、踩雷计数账)与 **BattleFacts**(战斗事实件:受理事实 encounter、轮 facts 缓冲、封印判定账、装板溯源、条件计数、同调快照;attune 状态两成员随件、行为函数留宿主)——外加两项单点处置:treasure_inventory 注入改址(level_runner 经 RewardGrant 出口直注,原「外部赋值路径零改址」句经用户追认失效)与 _hero_atk 转派生读。
|
||||
|
||||
什么状态算完:
|
||||
|
||||
1. 宿主类变量实测 15、两新件零 gdstyle 键、battle_orchestrator 全文件零超标键(第 9 节键账)。
|
||||
2. 游戏行为零变化:同种子完整局步骤流、事件流、两快照载荷逐位一致(第 4 节红线;第 11 节 V0 行)。
|
||||
3. 批末代码域闸全绿(冒烟+系统测试+单元集成关联档+探针+静态扫描),键账对账完成(第 12 节)。
|
||||
4. 实现报告与反哺点清单落 `reports/`(T4 产出物落位卡)。
|
||||
|
||||
## 2. 设计事实源
|
||||
|
||||
- `reports/设计-战斗编排类变量归约-2026-10-29.md`——设计讨论段定稿全文。逐成员去向(38 项五去向)、两新件形态与耦合边界、attune 重裁决、已否决切法、随迁键义务、行为零变化风险点、键账预期、改址盘点,全部以该文档对应节为唯一合同;本卡不复制其表格,T0 逐名对账时引用。
|
||||
- `design/engineering/architecture/architecture.md` v1.25——「战斗编排域拆件定稿」节轴丁两件(RoundCycle/BattleFacts,跨件单向接线、段类随动、attune 改判、S13 键账收敛义务、验收红线)与「模块归属·功能层」两行、「测试与质量域」S13 豁免第三条注销句——实现照册施工。
|
||||
- 五待裁点裁决(2026-10-29 用户裁,对应设计文档 §13):①encounter 归战斗事实件=采纳;②treasure_inventory 注入改址=追认(「外部赋值路径零改址」句失效);③attune 重裁决=采纳「状态归 facts、行为留宿主」;④完美账写口升级=采纳(grant_segment 三处直写改经 facts 三方法);⑤PARITY 对拍批准=批内实跑须用户点头、不重锚。
|
||||
|
||||
## 3. 现状事实(代码级,2026-10-29 实查;开工 T0 按当轮 master 重测复核)
|
||||
|
||||
- `tools/gdstyle_baseline.txt:9-10`——battle_orchestrator.gd 现登记两条类级键:`quality/max-class-variables = 38`、`quality/max-file-length = 1035`;**该文件零函数级键**(59 个函数全部在默认阈值内——设计文档 §7 前提成立,T0 复核)。
|
||||
- 宿主 38 类变量声明区=`battle_orchestrator.gd:37-85` 与 `:223-227`(逐名清单见设计文档 §2 表)。宿主改后保留 15:db、rng、minesweeper、action_economy、_enemy_system、_status_effects、_reward_economy、_damage、_fx_host、_reward_grant、round_index、battle_result、nest_preview_count、_rounds、_facts。
|
||||
- **编队前置实态**:迭代 42(gdstyle 尾波清偿批,roadmap 在册)合回后轴丙 BoardInstaller 已建——`_board_generator` 成员随件退役(38→37)、装板域六函数迁出、宿主复位块留薄壳 `_install_and_reset`、文件长键归绿;届时宿主约 890 行/37 成员,本卡叠加其上。**本卡在迭代 42 合回之前禁开工**;T0 按当轮 master 重测对账。
|
||||
- 段驱动现态:五段构造 `battle_orchestrator.gd:256-260`(授予/战斗两段三引用形,aura/decay/verdict 单引用形);三闸 `_maybe_settle` :592-597;段序体 `_settle` :602-613(终局早退不回置 _settling);开轮摇号 `_roll_round_actions` :677-721(behavior_roll 流 :717,mines_hits 转存 :720-721);`_on_round_end` 末行 :589 调 `_maybe_settle`。
|
||||
- 事实族写读点:缓冲追加 `_on_cell_revealed` :554-580(身份快照捕获 :576 留宿主);`_on_seal_judged` :583;`_facts_path` 写 `_on_round_end` :588;轮复位 `_reset_round_facts` :976-979(三调用点 :273/:810/:862);封印/完美/标错/板序/溯源清零在装板复位块 :442-446(迭代 42 后归宿主薄壳);`_refresh_used_this_round` 复位点 `_exit_distribution` :811;完美谓词 `perfect_sweep_earned` :1033-1035。
|
||||
- treasure_inventory:宿主声明+setter 转发块 `battle_orchestrator.gd:48-52`;唯一外部注入点 `level_runner.gd:520`;宿主读 :111/:203/:450/:858;`grant_segment.gd:370-371` 读 `oc.treasure_inventory`。
|
||||
- _hero_atk:声明 `battle_orchestrator.gd:227`、受理写入 :304、spawn 消费 :305、`combat_segment.gd:56` 消费 `oc._hero_atk`。
|
||||
- attune 外部三面(零改址标的):`attune_has` 公有面消费=table_structure_guard_test 起战断言(:162/:166)与 breakpoint_resume_test;`attune_param_sum`=main.gd:567 与 treasure_effects_test;`attune_convert_state`=treasure_interact_controller.gd:125。三面全部留宿主公有面。
|
||||
- 冻结面:`nest_preview_count` 外部直读=main.gd:536-537+treasure_effects_test:153;`round_index` 公有直读=system_test.gd:447-462(st.round_index)等四套件约 15 处。
|
||||
- **设计文档 §11 漏列一处(T0 实查补入)**:`settle_segments_test.gd:27` 接线断言 `oc._grant_seg != null and oc._grant_seg.oc == oc`——段件迁 RoundCycle 后必红,须改指 `oc._rounds._grant_seg`。
|
||||
- `tools/run_all_gates.sh` PARITY_TOUCH_FACES(:161 定义区)含 `game/core/battle_orchestrator.gd`——本批必触面。
|
||||
- `game/tests/static_scan.sh`——S8 await 文件集(:317,9 文件)与 S7 B1 域文件集(:359,9 文件)均未含两新件路径;round_cycle.gd 经 oc 调 B2 符号(`_enemy_system` 族)须随批增行,battle_facts.gd 零协作调用不入清单。
|
||||
|
||||
## 4. 设计契约(违反即返工的红线条款)
|
||||
|
||||
- 🔴 **行为零变化(本批总判据)**:同种子下事件流/步骤流/两快照载荷/存档往返逐位一致;玩家可见面零变化;`design/gdd/systems/` 零修订预期。
|
||||
- 🔴 **RNG 取号序零漂移(封闭流随件迁移先例句)**:behavior_roll 随 `roll_round_actions` 迁 RoundCycle——流名、开流时点、取号序逐字(先例句=「fx_reveal 封闭流随件迁移取号序不变」同款);encounter/gp_drop/board_gen/variant_place/fx_reveal 五流留原地零触碰;零 `randomize()`/自建随机。
|
||||
- 🔴 **信号顺序契约冻结**:五信号(step_row/battle_finished/round_started/board_changed/settlement_snapshot)留宿主;发射语句零迁移、发射时序零变化;A2 三 connect(:251-254)逐字。
|
||||
- 🔴 **两快照出口签名与载荷逐字不变**:presentation_snapshot/diagnostic_snapshot 字段名、嵌套结构、值口径逐字——内部读数改指两件投影后值恒等(round_index/attune_safe_seen/完美三账/hero_atk 派生读均受理后不变量)。
|
||||
- 🔴 **明细行协议词表零触碰**:基础 9 类+扩展行词表、SOURCE_EXEMPT_TYPES/SOURCE_EXEMPT_CLASSES 两常量、`_emit_row`/`_assert_row_source` 行发射基建留宿主零迁移。
|
||||
- 🔴 **PARITY 触面**:battle_orchestrator.gd 触 PARITY_TOUCH_FACES——实跑对拍须经用户批准、不得借机重锚。
|
||||
- 🔴 **拆分边界纪律**(判据权威=code-conventions §1.1,此处立卡内执行条款):①每个拆出单元须有可陈述的职责语句与单一变化原因(实现报告逐件一行承载);②拆出单元须有集体身份——命不出名字、只能说「剩下的成员」的打包=凑计数袋,禁;③「过阈值」只许作为发现信号,作为拆分或收拢的动机即违规;④按纪律拆不出内聚单元 → 停卡呈报走豁免/还债通道,禁硬拆凑绿;⑤拆分沿职责轴不沿阈值轴。两新件职责语句见第 8 节(RoundCycle=轮结算周期的推进结构;BattleFacts=战斗事实的记录与查询口径)。
|
||||
- 🔴 **禁为机检文本保留无效成员**:22 成员随件迁出+treasure_inventory/_hero_atk 两成员退役=宿主删 24 项(37−22−2+RoundCycle/BattleFacts 两新件接线引用=宿主 15,账平——grilling 复核订正原算术),禁保留别名、别名转发属性或空壳;机检键与卡片契约互斥时,实现段一律停卡呈报,不得自造第三条路。
|
||||
- 🔴 **随迁键收敛义务**:迁移函数逐字纪律——`roll_round_actions`(45 行/分支≈8 贴线)、`settle_if_due`、`reset_round`、三 mark 方法迁移与改指**禁顺手增分支/局部**;函数迁入新文件若出超标键=卡内同步收敛(拆助手函数,拆分不改语义;先例=迭代 40 卡① 12 随迁键收敛),禁带新键进批末闸。
|
||||
- 🔴 **段类接线改形守 Middle Man 禁壳**:段类对宿主的直调形态不变(段类经宿主引用直调,现状形态);段内改指一律调用点改指(`oc._X` → `oc._facts.X`/`reward_grant.treasure_inventory`),宿主与新件禁留转发壳。
|
||||
- 🔴 **_fatal 与 battle_result 状态机唯一写点留宿主**:RoundCycle/段类经 oc 直调 fatal 面零改形;BoardInstaller(迭代 42 建件)fatal Callable 零触碰。
|
||||
- 🔴 **BattleFacts 成员冻结**:15/15 贴顶——实现期禁增员,增员即停卡;扩容阀=下一张要加事实成员的卡先把封印判定账五成员二次拆出(SealLedger,−5)再落新账,禁硬挤。
|
||||
- 🔴 **reset_round 复位边界**:只清 reveals/seals/path 三项、**不碰 refresh_used**——_battle_over 后快照读到的 refresh_used 必须保持末轮值(设计文档 §8.5 险点,对照表 V2 行断言钉住)。
|
||||
|
||||
## 5. 范围边界
|
||||
|
||||
做什么:设计文档 §2 逐成员去向表的全部迁移与改址、两新件建件、treasure_inventory 改址、_hero_atk 派生读、随迁键收敛、S7/S8 静态扫描随动、对照表新增断言四条。
|
||||
|
||||
不做什么:
|
||||
|
||||
- 轴丙 BoardInstaller 建件——迭代 42 在册卡执行,本卡前置、不重复。
|
||||
- 五段段类职责与段序语义零改写(只改指);`_exit_distribution` 留宿主(设计文档 §6.5 已否决迁驱动件——判定段直调宿主,零新引用环)。
|
||||
- attune 行为函数留宿主(attune_has/attune_param_sum/attune_convert_state/积点自动兑付体/充能重置零迁——设计文档 §5 重裁决);AttuneLoadout 零触碰。
|
||||
- nest_preview_count 冻结面、round_index 公有直读面、A2 三事件订阅面——零变化。
|
||||
- 数值表、RNG 流词表、信号载荷 schema、明细行词表——零触碰;本批零数值改动,MC 零跑(第 13 节)。
|
||||
- `game/tests/README.md`、`design/` 全目录、根规则文件——实现批禁写(反哺点通道,第 6 节)。
|
||||
- 效果发射端口定形与 reward_economy 分件——归接收方条目其余子项,另行设计讨论。
|
||||
|
||||
## 6. 关联文档同步面
|
||||
|
||||
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|
||||
|---|---|---|
|
||||
| design/engineering/architecture/architecture.md | 轴丁两行与功能层 RoundCycle/BattleFacts 行——设计已闭合落文 v1.25,实现照册施工;「测试与质量域」S13 豁免第三条注销句已预写注销(本批键账达成即生效,未达成=停卡非落文);两行「构造=引用束注入」句与本卡三参直构/零参直构实态的口径差;批末成员数/行数/公开方法数实测值与在册数字出入 | 设计权威文档——实现批禁直改;出入逐条列进 `reports/iter<N>-反哺点-<日期>.md`,用户裁决后归文档批落文 |
|
||||
| game/tests/README.md | 本批零新增能力、零入口与代表用例名变更(测试改指只动成员寻址;新增断言四条全部内嵌既有函数);能力清单零增删改 | 机械面文档——实现批禁写;批末收尾核对表上名字与实际落地一致(改名则回表) |
|
||||
| design/gdd/systems/(全树) | 无关联文档——结构整改不改游戏规则与玩家可见行为 | 无修订预期;若实现中发现契约句被触碰,停卡呈报走反哺点通道 |
|
||||
|
||||
## 7. 卡前文件结构图
|
||||
|
||||
| 文件 | 职责 | 改动性质 |
|
||||
|---|---|---|
|
||||
| game/core/battle_facts.gd | 战斗事实件(新增,architecture v1.25 功能层在册)——受理事实/轮 facts 缓冲/封印判定账/溯源/条件计数/同调快照,自带轮复位与完美账写口 | 新增(非行为改动——成员迁移;验收=对照表 V1/V2/V6 行) |
|
||||
| game/core/settlement/round_cycle.gd | 轮循环驱动件(新增,同在册)——五段段件持有与段序执行、结算重入门闸、开轮摇号、踩雷计数账 | 新增(非行为改动;验收=V1/V3 行) |
|
||||
| game/core/battle_orchestrator.gd | 战斗结算编排中枢——宿主 15 成员定着、行发射基建、状态机、两快照出口、attune 行为读数与触发面 | 修改(非行为改动——成员改指、三函数迁出、派生读、注入改址;验收=V0–V5 行) |
|
||||
| game/core/settlement/grant_segment.gd | 授予段——事实族改指约 23 处+完美三处直写改经三 mark 方法 | 修改(非行为改动) |
|
||||
| game/core/settlement/combat_segment.gd | 战斗段——2 处改指(oc._facts_reveals 扫描、oc._hero_atk 派生调) | 修改(非行为改动) |
|
||||
| game/core/level_runner.gd | 关卡域生命周期——库存注入 1 行改经 `reward_grant()` 出口直注 | 修改(非行为改动——注入路径改址,注入时序与消费面零变化;验收=V5) |
|
||||
| game/tests/static_scan.sh | 静态扫描域承载——S7 B1 域文件集与 S8 await 文件集增行 round_cycle.gd | 修改(工程随动,architecture 拆件定稿节 S7/S8 随动条在册) |
|
||||
| game/tests/unit/battle_settlement/seal_polarity_test.gd · unit/core/feat_vouchers_test.gd · unit/battle_settlement/trigger_cond_test.gd · unit/battle_settlement/round_flow_skill_pool_test.gd · unit/core/settle_segments_test.gd · unit/core/treasure_effects_test.gd · unit/core/adventure_feats_test.gd · unit/core/meta_progression_forge_test.gd · unit/battle_settlement/roll_multiplier_test.gd | 成员寻址改指(断言条件与期望值零变化)+新增断言内嵌既有函数(V1/V2/V4/V5) | 修改(改指=非行为改动;新增断言行=对照表对应行) |
|
||||
|
||||
aura/decay/verdict 三段、battle_fx_host、reward_grant、damage_controller、main.gd、treasure_interact_controller、board_installer——零改动(设计文档 §11 盘点)。新增件「为什么不能复用」理由与唯一落点核查见第 8 节;对不上即卡片不成立。
|
||||
|
||||
## 8. 落位与可复用性预检
|
||||
|
||||
- **battle_facts.gd(新增)**:复用面核查——战斗事实记录面现行只摊在 battle_orchestrator 成员区(全仓 grep 同名与同义标识符:`_facts_reveals`/`_seal_consumed`/`_perfect_*` 等无第二实现),无既有件可复用。不能并入 BattleFxHost(效果引擎宿主域——变化原因是效果发射与施加,不是事实记录)、不能并入 RewardGrant(授予管线域——事实账不是授予物)、不能并入五段段类(段类只搬运时序零持有账——缓冲写读跨段跨界,归宿主编排面)、不能并入 AttuneLoadout(营地/冒险域充能物化单源,迭代 39 已闭合契约——重开已闭合边界=设计文档 §5 理由 4 否决)。落点唯一:`game/core/battle_facts.gd`。分层:core 层 RefCounted,零注入引用、零信号、零协作对象调用——纯数据+谓词+写口;身份快照捕获(query_full_snapshot)留宿主 `_on_cell_revealed`,防它变成第二编排面。
|
||||
- **round_cycle.gd(新增)**:复用面核查——轮结算周期推进机构(段件持有/重入闸/摇号/踩雷账)现行只存在于宿主三函数+五成员,无第二实现。不能并入 BattleFxHost/RewardGrant(变化原因不同,同上)、不能并入任一段类(它是段件的序主人——持段件者不能是被持者)。落点唯一:`game/core/settlement/round_cycle.gd`(与五段段件同目录)。分层:core 层 RefCounted、零 await;随机只经 `oc.rng` 的 behavior_roll 封闭流。
|
||||
- **引用束注入构成**:引用束先例(BattleFxHost/RewardGrant 的字典束)防的是 `_init` max-parameters 新键——本批两新件参数均未触发:RoundCycle `_init(host, fx_host, reward_grant)` 三参直构(fx_host/reward_grant 仅作段构造透传,不落成员);BattleFacts 零参直构。architecture 两行「构造=引用束注入」句按设计文档 §3/§4 实态执行(三参直构无需束),出入随反哺点申报。
|
||||
- **依赖方向**:宿主→两新件单向(宿主 `_init` 建件并接线,每战新建同灭);RoundCycle 持 `oc`=五段段类既定同款形态(段类已持宿主引用直调——非新增反向引用),除 `oc` 外禁持宿主其他成员、禁回调宿主私有族;BattleFacts 不持任何对象引用——宿主与段类经注入引用直读写(fx_host._fx_bonus_delta 跨件直读写同款现状形态)。新件之间零互引。
|
||||
- **新增函数**:宿主 `_hero_atk()` 派生读=`_journal()`「读面即引用、无第二账」同款先例(encounter 受理后只读,派生值恒等);`reset_round`=原 `_reset_round_facts` 逐字;三 mark 方法=新写口(升级采纳案)。零新增数据件、零新增常量表。
|
||||
|
||||
## 9. 实现规范预算(新件对照 gdstyle 默认阈值;写码前对账,超预算面=停卡退回写卡段)
|
||||
|
||||
| 新件 | 公开方法 ≤20 | 类变量 ≤15 | 迁移函数对账(基线源函数键) |
|
||||
|---|---|---|---|
|
||||
| battle_facts.gd | 预算 4(reset_round+mark 三方法;设计文档 §10 表载 5 属含 `_init` 宽口径计数差,两口径均 ≤20 零键风险) | 15(贴顶——实现期禁增员,增员即停卡;扩容阀=SealLedger 二次拆出) | `reset_round`=原 `_reset_round_facts` 逐字(基线无其函数级键);三 mark 新增小函数远在阈值内 |
|
||||
| round_cycle.gd | 预算 3(settle_if_due/roll_round_actions/is_settling) | 8(oc+五段段件+_settling+mines_hits) | `settle_if_due`=`_maybe_settle`+`_settle` 合体(两源函数基线零键;闸序与段序逐字);`roll_round_actions` 45 行/分支≈8 贴线——迁移禁增分支/局部,确需增条件即停手核对 gdstyle;`is_settling` 新增小函数 |
|
||||
|
||||
存量触面一查:battle_orchestrator 类变量 37(轴丙后实测)→15 只降、文件长约 890→约 830 只降(均阈值内,S13 键较登记值只降不升——达成手段=本卡迁移,无豁免申报);grant_segment/combat_segment 改指零新增键(`_judge_seal` 等函数体只换成员寻址);level_runner 改 1 行零新增键。两新件与改址后宿主、段类落地后先跑 `python tools/gdstyle_gate.py` 预检一次再进批末闸(T4 步骤)。`_init` 形态:RoundCycle 三参/BattleFacts 零参(max-parameters 阈值 5 未触发)。新增文件全类型标注(S9——容器参数化走 `Dictionary[Variant, Variant]` 现行口径);头注按 code-conventions §1.4.1(职责语句+封闭面声明,禁变更叙事、禁文档反链)。
|
||||
|
||||
## 10. 任务卡 T0..T4(估时为区间;工作量限制只属迭代层)
|
||||
|
||||
**T0 重测对账(0.25–0.5 工作日)**(前置:迭代 42 合回——BoardInstaller 在库;产出:逐成员对账结论与改址点名清单,后续各卡取用)
|
||||
|
||||
- [ ] 以当轮 master 重测 battle_orchestrator.gd 类变量逐名清单,对账设计文档 §2 表五去向(留宿主/RoundCycle/BattleFacts/退役改址/派生读;轴丙后实态 37 项,`_board_generator` 行应已消失)——对不上即停卡呈报
|
||||
- [ ] 复核 gdstyle 基线:battle_orchestrator 函数级键数(预期零——漂移即停卡呈报);类变量键现值与文件长键现状(应已随轴丙归绿或基线已 refresh)
|
||||
- [ ] 复核第 3/7/9 节全部 file:line 引用与设计文档 §11 改址盘点实数(grant_segment 约 23–25 处、测试各套件逐处点名——含 settle_segments_test:27 补入项);漂移处就地改卡并记录
|
||||
|
||||
**T1 BattleFacts 建件与事实成员迁移(0.75–1 工作日)**(取用:T0 对账清单;产出:`_facts` 在座、事实族 15 成员归件——T2/T3 引用其成员名)
|
||||
|
||||
- [ ] 建 `game/core/battle_facts.gd`:class_name BattleFacts,extends RefCounted;15 类变量初值逐字承原宿主声明(encounter/reveals/seals/path/refresh_used/board_seq/board_from_midround/seal_consumed/seal_miss_seen/perfect_hit_true/perfect_hit_false/perfect_forgiven/feat_first_dig_used/attunement/attune_safe_seen);公开方法 4:`reset_round()`(原 `_reset_round_facts` 逐字——只清 reveals/seals/path 三项,不碰 refresh_used)、`mark_perfect_hit()`、`mark_perfect_miss()`、`mark_perfect_forgiven()`;头注写职责语句+成员封闭面+零注入零信号零协作调用
|
||||
- [ ] 宿主 `_init` 建 `_facts = BattleFacts.new()`;事实族成员全量改指:宿主声明删 15 项、读写点改 `_facts.X`(encounter 全部读点——_journal/_attune_loadout/_fx_host_fact/受理段/fx_state/两快照/gp_drop,按 T0 点名清单逐处;缓冲追加/复位/装板清零/perfect 谓词同批);`_reset_round_facts` 函数删除,三调用点改调 `_facts.reset_round()`(时序位置逐字)
|
||||
- [ ] grant_segment 事实族改指(`oc._facts_reveals/_facts_seals/_facts_path/_seal_consumed/_seal_miss_seen/_feat_first_dig_used/_perfect_*` → `oc._facts.X`);完美三处直写改经三 mark 方法(:311/:379/:394——写口升级采纳案;:397 forgiven 读数直读 `_facts.perfect_forgiven` 零变化)
|
||||
- [ ] 测试改指:seal_polarity_test 8 处(_perfect 直写→_facts.perfect_*)、feat_vouchers_test facts 族、treasure_effects_test:309(ob14.attunement→ob14._facts.attunement)、adventure_feats_test 1 处(encounter 读→_facts.encounter)——断言条件与期望值零变化
|
||||
- [ ] 新增断言 round_flow_skill_pool_test.gd:_smoke_full_battle 内嵌〔编排归约 V2〕:终局后 `presentation_snapshot()["refresh_used"]` 等于末轮结算 snapshot 的 economy.refresh_used(复位边界险点,规格见对照表)
|
||||
- [ ] 孤立验证:`godot --headless --script res://tests/run_all.gd -- --only=seal_polarity,feat_vouchers,treasure_effects,adventure_feats,table_structure_guard,round_flow_skill_pool,variant_placement` 全绿+`python tools/run_smoke.py`(出红只跑红件最小单元)
|
||||
|
||||
**T2 RoundCycle 建件与段驱动迁移(0.75–1 工作日)**(取用:T1 的 `_facts`;产出:`_rounds` 在座、段驱动三入口——T3 引用其方法名)
|
||||
|
||||
- [ ] 建 `game/core/settlement/round_cycle.gd`:class_name RoundCycle,extends RefCounted;类变量 8(oc/mines_hits 公有+_grant_seg/_aura_seg/_combat_seg/_decay_seg/_verdict_seg/_settling 私有);`_init(host, fx_host_ref, reward_grant_ref)` 三参——五段构造五行从宿主 `_init` 逐字搬入(构造参数与持有形态不变);公开方法 3:`settle_if_due()`(原 `_maybe_settle` 三闸+`_settle` 段序体合体——闸序 settling→battle_result→phase 逐字,终局早退不回置 _settling)、`roll_round_actions()`(原函数逐字迁入——behavior_roll 流名/开流时点/取号序逐字,宿主引用经 oc 改指,禁增分支/局部)、`is_settling()`;头注写职责语句与单一变化原因
|
||||
- [ ] 宿主 `_init`:五段构造五行迁出,改 `_rounds = RoundCycle.new(self, _fx_host, _reward_grant)`(置于两件建齐与 bind 接线之后——构造序禁环不变);五段成员声明删除;`_maybe_settle`/`_settle`/`_roll_round_actions` 三函数删除
|
||||
- [ ] 宿主调用点改址:`_on_round_end` 末行→`_rounds.settle_if_due()`;begin_battle 与 `_exit_distribution` 的 `_roll_round_actions()`→`_rounds.roll_round_actions()`;diagnostic_snapshot settling 读→`_rounds.is_settling()`;`_begin_battle_fx_state` 踩雷清零→`_rounds.mines_hits = {"total": 0, "last": 0, "round": 0}`(赋值复位——语句时点逐字);`_book_negative_blast` 两写→`_rounds.mines_hits`
|
||||
- [ ] 测试改指:trigger_cond_test :119/:126/:131(orch._mines_hits→orch._rounds.mines_hits);settle_segments_test :27(→oc._rounds._grant_seg);round_flow_skill_pool_test:1022 与 feat_vouchers_test 5 处(_grant_seg→_rounds._grant_seg)
|
||||
- [ ] 新增断言 settle_segments_test.gd(接线检查段内嵌)〔编排归约 V1〕:oc._rounds 非空且 `_rounds.oc == oc`、五段段件齐在 _rounds、oc._facts 非空(规格见对照表)
|
||||
- [ ] `game/tests/static_scan.sh` S8_FILES(:317)与 S7_B1_SET(:359)增行 `game/core/settlement/round_cycle.gd`(battle_facts.gd 零协作调用不入两清单)
|
||||
- [ ] 孤立验证:`-- --only=round_flow_skill_pool,settle_segments,trigger_cond,seal_polarity,skill_unlock,roll_multiplier,variant_placement` 全绿+冒烟
|
||||
|
||||
**T3 宿主改形收束(0.5–0.75 工作日)**(取用:T1/T2 两件与成员名;产出:宿主 15 成员定着)
|
||||
|
||||
- [ ] 宿主 `_rounds`/`_facts` 成员声明落位;已迁成员声明复核清零——类变量实测 15(第 3 节名单),禁无效成员
|
||||
- [ ] treasure_inventory 改址:宿主成员与 setter 转发块(:48-52)删除;四处读改指 `_reward_grant.treasure_inventory`(_hook_attune_consume/_reseed_attune_charges/装板薄壳叠加层退役/_battle_over 叠加层退役);`level_runner.gd:520` 改 `_settlement.reward_grant().treasure_inventory = treasure_inventory`(注入时序在宿主构造之后不变)
|
||||
- [ ] _hero_atk 派生读:宿主新增私有函数 `_hero_atk() -> int`(返回 `int(_facts.encounter.get("hero_atk", int(db.combat.hero.atk)))`);受理段写入与 spawn override 改调;`combat_segment.gd:56` oc._hero_atk→oc._hero_atk();_hero_atk 成员删除
|
||||
- [ ] attune 读数出口核验:attune_has/attune_param_sum/attune_convert_state/_attune_charge_safe_row/_attune_safe_seen_read 读源改 `_facts.attunement`/`_facts.attune_safe_seen`——三个外部消费面(main.gd:567、treasure_interact_controller.gd:125、table_structure_guard_test/breakpoint_resume_test 起战断言)零改址零触碰
|
||||
- [ ] 新增断言 roll_multiplier_test〔编排归约 V4〕与 treasure_effects_test〔编排归约 V5〕(规格见对照表)
|
||||
- [ ] 孤立验证:`-- --only=roll_multiplier,treasure_effects,breakpoint_resume,level_shop_economy,round_flow_skill_pool` 全绿+`python tools/run_system_test.py`
|
||||
|
||||
**T4 键账对账与收口(0.25–0.5 工作日)**(取用:T0–T3 全部产出;产出:本批交付物)
|
||||
|
||||
- [ ] `python tools/gdstyle_gate.py` 预检一次——宿主类变量 15、round_cycle 8、battle_facts 15、文件长 ≤1000(预期约 830)、零基线外新键;出超标键→按第 4 节随迁键收敛义务卡内拆助手后复检
|
||||
- [ ] 里程碑步出口跑全套闸:`bash tools/run_all_gates.sh --code` 全绿(改动全为代码面);闸 11 PARITY 触面按第 4 节条款——实跑对拍须用户批准发起、不得借机重锚,NEED-APPROVAL 时停步呈用户裁决
|
||||
- [ ] 键账对账:第 9 节预期逐键核;基线 refresh 由用户发令人工 `python tools/gdstyle_gate.py --refresh`(须 --force——全基线 16 键消失 ≥2 条触发骤降守卫;与姊妹卡同批编队时一次 refresh 合并执行)
|
||||
- [ ] 产出物落位卡:`reports/iter<N>-实现报告-<日期>.md`(各卡状态+实机目检总清单+实现决定记录+逐拆出单元职责语句一行)与 `reports/iter<N>-反哺点-<日期>.md`(第 6 节同步面逐条落点)写齐方算收口
|
||||
|
||||
合计估时约 2.5–3.75 工作日(设计文档 §12 载 2–3 日;上探余量=测试改址逐处点名与 PARITY 批跑配合;PARITY 实跑须用户在场批准,不占卡估时)。切分预案:T1/T2 迁移函数出超标键需卡内拆助手时,超软盒预挂改由 T3 并 T4 吸收。
|
||||
|
||||
## 11. 验证闸——改动—验收对照表
|
||||
|
||||
域口径:本批改动全为 `game/` 下非 .md 行为载体——批末跑代码域闸(`tools/run_all_gates.sh --code`);里程碑步(T 段)出口跑一次全套闸,波内修复只做出红最小单元的最窄确认,新增测试先行孤立验证再并入全套。测试执行两入口铁规不破。三件保险(冒烟/系统测试/静态扫描)恒跑;02 单元与集成按关联档选套件(上表落点套件并集)。能力清单:本批零新增能力、零入口与代表用例名变更——能力行全部为既有名,零增删改(第 6 节)。**静态判据申报(不入对照表)**:键账收敛与静态随动(宿主 38→15、round_cycle 8/battle_facts 15、零基线外新键、static_scan.sh S7/S8 两清单增行)无运行时可观测提交面——判据=`python tools/gdstyle_gate.py` 与 `game/tests/static_scan.sh` 退出码(T4 执行),属静态判据+评审注记申报观测面局限(test-conventions §8.4 出口)。
|
||||
|
||||
| 行 | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| V0 | 行为零变化(本批总判据) | 全部结构改动(第 7 节清单) | PARITY 同种子完整局对拍(`tools/parity_anchor.py`,用户批准后实跑、禁重锚);关联套件零改址应绿 | 集成+对拍 | 真实局 begin_battle→挖掘→结算→终局 | step_row/settlement_snapshot 逐位一致——差异非零即停机呈报 | 既有:回放确定性(同种子三变体逐位) |
|
||||
| V1 | 两新件建件接线(T1/T2) | battle_facts.gd/round_cycle.gd 新建;宿主 _init 建件接线;五段构造迁 round_cycle | 新增 settle_segments_test.gd 接线检查段内嵌〔编排归约 V1〕:`oc._rounds` 非空且 `_rounds.oc == oc`;五段段件齐在 `_rounds`;`oc._facts` 非空 | 单元 | BattleOrchestrator 直构(settle_segments_test 现行夹具同款) | 编排器接线面(新件在座与宿主回指——接线断言本体) | 既有:轮内流与结算五段全序 |
|
||||
| V2 | reset_round 复位边界(险点) | battle_facts.reset_round 只清三缓冲;宿主三调用点改调 | 新增 round_flow_skill_pool_test.gd:_smoke_full_battle 内嵌〔编排归约 V2〕:终局后 `presentation_snapshot()["refresh_used"]` == 末轮结算 snapshot `economy.refresh_used` | 单元 | begin_battle→轮内刷新→停手→结算→终局 | 两快照同键值恒等(复位不碰 refresh_used 的可观测提交面) | 既有:轮内流与结算五段全序;既有:停手转存储备与轮内刷新(上限/AP 不重置/刷新图零清图奖励) |
|
||||
| V3 | 段驱动与摇号迁移(重入门闸/settle_if_due/roll_round_actions/mines_hits 账) | 三函数迁出宿主;宿主调用点改址;trigger_cond_test 3 处改指 | 复用 round_flow_skill_pool_test 全套(_smoke_full_battle/_smoke_settlement_segments/_smoke_skill_pool_replay_independence)、settle_segments_test V4-3 真实一轮、skill_unlock_test、trigger_cond_test(改指后应绿)——零新增断言 | 单元 | begin_battle;stop→WAITING→settle_if_due | 五段裁定行序+settling 闸+终局早退+同种子摇定逐位(behavior_roll 流随件零漂移由既有回放断言钉住)+mines_hits 转存读数 | 既有:轮内流与结算五段全序;既有:技能池数据面与回放独立;既有:Boss 半血解锁技门控 |
|
||||
| V4 | _hero_atk 派生读 | 成员删→私有函数;combat_segment.gd:56 改调 | 新增 roll_multiplier_test.gd(既有主角攻击链函数内嵌)〔编排归约 V4〕:enc 携 `hero_atk` override 起战→主角攻击单 base_value==override;缺省→base_value==hero 表值 | 单元 | begin_battle(enc)→战斗段主角先手 | 主角攻击单基值(受理后派生值恒等的判据本体) | 既有:伤害公式与掷点乘区 |
|
||||
| V5 | treasure_inventory 注入改址 | level_runner.gd:520 改经 reward_grant() 出口;宿主四处读改指;宿主 setter 转发块删 | 新增 treasure_effects_test.gd(秘宝使用链内嵌)〔编排归约 V5〕:注入后 `current_battle().reward_grant().treasure_inventory` 与关卡库存同一引用,且 use_treasure 受理走通 | 单元 | LevelRunner 建战注入→use_treasure 四步 | 注入引用同一性+受理面走通(改址后消费面不断链) | 既有:秘宝结构冻结与 12 件效果 |
|
||||
| V6 | 封印判定账/装板溯源/受理事实迁移(完美写口升级、attune 状态随件) | 事实族改指(grant_segment 约 23 处+测试);三 mark 写口;attune 读源改 _facts | 复用 seal_polarity_test 全套、feat_vouchers_test(契约 2 计数纯净 R2)、variant_placement_test、meta_progression_forge_test、adventure_feats_test、table_structure_guard_test(attune 面零改址应绿——本批最硬的外部面零变化证)——零新增断言 | 单元 | 封印动作→结算;begin/refresh/exit 装板;begin_battle(enc) | 完美三账读数+去重闸+契约 2 计数纯净;刷新图零清图奖励+board_seq;enc 携带键贯通;attune_has/param_sum/convert_state 外部面零变化 | 既有:封印与极性路由/不可逆;既有:清图奖励双份与零路径;既有:变异布置门控;既有:专长(奇物)授予与凭证保底;既有:元进度入账与锻造两轴;既有:装板与开局免费展开(封锁格无资源、计入清图) |
|
||||
|
||||
反向核对:diff 中每个行为载体改动均有行——本批申报**行为改动零条**(全部为非行为改动:成员迁移与调用点改指,判断依据=V0 同种子逐位一致证明+既有断言面零改址应绿;完美写口升级=同一时点同一增量改经方法单点,语义逐字)。新增断言四条(V1/V2/V4/V5)全部挂行;孤儿断言零条。测试削弱申报见第 15 节。
|
||||
|
||||
## 12. 基线纪律(S13 键账)
|
||||
|
||||
1. 本卡键账目标=battle_orchestrator 类变量键归绿(实测 15 后随 refresh 消失);文件长键已由轴丙(迭代 42)归绿,本卡保持文件长 ≤1000(预期约 830)。
|
||||
2. 禁为过闸 refresh 换绿:基线重生成只由用户发令,批末键账对账后人工 `python tools/gdstyle_gate.py --refresh` 一次执行(禁闸内自动重生成、禁实现批中途 refresh)。
|
||||
3. 重锚守卫:新基线键数较旧基线少逾 10% 须 `--force` 显式确认——本批与轴丙预期合计消失 ≥2 条(16 键基线),须带 `--force` 由用户执行。
|
||||
4. 还债=数值下降自然绿:迁移后同键数值下降不判红;出现恶化(同键数值较登记值上升、基线外新键)=停卡呈报,禁自行消化。
|
||||
5. S13 豁免第三条(battle_orchestrator max-class-variables,architecture v1.25 已预写注销句)随本批达成生效——未达成=停卡呈报,非落文事项。
|
||||
|
||||
## 13. MC/数值与 RNG 零触碰声明
|
||||
|
||||
本批零数值改动、零数据表改动、零 RNG 流词表改动、零玩法字面量引入——结构整改不改数值与 RNG 消费序。behavior_roll 封闭流随件迁移取号序不变(流名、开流时点、取号序逐字)。数值与 RNG 零触碰则 MC 零跑;battle_orchestrator.gd 触 PARITY_TOUCH_FACES——实跑对拍须经用户批准、不得借机重锚(批末闸 11 判 NEED-APPROVAL 时由用户裁决:批准实跑或裁跳过,卡内不定案)。
|
||||
|
||||
## 14. 异常分级
|
||||
|
||||
- **L1 自救**:改指漏改编译错、测试寻址漏改——就地修复重跑最窄确认。
|
||||
- **L2 记录继续**:实测行数/改指处数与设计文档「约」值区间偏离、头注指址微调——记入实现报告「实现决定记录」。
|
||||
- **L3 停机写报告等用户**:①机检预算互斥——两新件实数超第 9 节预算、BattleFacts 需增员、或迁移函数现出超标键=上游缺陷停卡退回写卡段(禁自造第三条路);②encounter 归属被实现期证伪——受理事实与轮 facts 复位节奏冲突实锤、且设计文档 §6.3 两条砍路均破冻结面(宿主 16 不可达)=停卡呈报走判据④通道;③T0 对账不符(成员去向对不上、基线出现函数级键、file:line 漂移过大);④V0 对拍差异非零(行为零变化被证伪);⑤PARITY 触面处置分歧;⑥断言面被下游兜底吸收致判据绑不上(按 test-conventions §8.4 出口呈报);⑦S13 键恶化或基线外新键。
|
||||
|
||||
## 15. 测试削弱申报(允许改动的旧断言及理由)
|
||||
|
||||
零申报——本批不删任何断言、不改判据阈值、不缩扫描面、不把真实入口换成下层直调;测试改指只动成员寻址(断言条件与期望值零变化);新增断言四条(V1/V2/V4/V5,全部内嵌既有函数)。未申报的削弱由独立验收审计判红。
|
||||
|
||||
## 16. 独立验收审计
|
||||
|
||||
合并前由未参与实现的会话或子代理执行;报告落 `reports/iter<N>-验收审计-<日期>.md`。审计至少做四件事(test-conventions §8.7):逐行核对第 11 节对照表(测试存在、真执行、尾缀可 grep、真实入口未绕过改动点);抽查判据绑定面(V2 两快照同键、V4 攻击单基值、V5 引用同一性——当轮真实跑批执行过);检查测试削弱(对照第 15 节零申报);核对全部「非行为改动」判定依据(零漂移证明是否在当轮真实跑批中成立、PARITY 批准凭据在案)。未过不得合并。
|
||||
|
||||
## 17. 代拍板白名单(允许 agent 自行拍板的微决策)
|
||||
|
||||
1. 迁移函数与改指处头注/行注的指址微调(词表与语义不动——「指址须真」纪律)。
|
||||
2. 调用面改指的机械改写(排版、注释同步、行内换行)。
|
||||
3. 断言失败消息尾缀编号分配与措辞(〔编排归约 Vn〕系列)。
|
||||
4. 新件私有成员与小函数命名微调(职责语义不变、公有面契约名逐字不动)。
|
||||
5. 宿主 _init 内两新件建件语句的次序微调(约束不变:_facts 无依赖先建、_rounds 在两件建齐与 bind 接线之后)。
|
||||
|
||||
超清单决策记入实现报告「实现决定记录」节。
|
||||
|
||||
## 18. 待裁点
|
||||
|
||||
零待裁点——五项待裁点(设计文档 §13)已由用户 2026-10-29 全裁闭合(第 2 节裁决记录),完美账写口升级已按推荐案采纳落卡。**零待裁点,开工门=U0**。编队前置:迭代 42(gdstyle 尾波清偿批,含轴丙 BoardInstaller)合回之后开工;T0 按当轮 master 重测对账。
|
||||
@@ -0,0 +1,195 @@
|
||||
# 需求卡片——测速循环批(tune_sim_controller 循环内 await 真实消除)
|
||||
|
||||
> **版本状态**:v1.0 定稿——零待裁点(2026-10-29 用户裁:信号步进状态机形态、收尾置假还原作为已申报行为改动、双实现对拍入批、错误路径差异接受并文档化)。
|
||||
> **接收方**:待办清单条目「零豁免五键清偿批——S13 余量五键真修四卡(2026-10-29 登记,来源=会话提及)」——本卡为其四卡中的测速循环批卡。
|
||||
> **来源**:reports/设计-测速循环去await-2026-10-29.md(2026-10-29 设计闭合)。**唯一事实源**:`reports/设计-测速循环去await-2026-10-29.md` + `design/engineering/architecture/architecture.md` v1.25「测试与质量域」S13 测量面豁免注销句(2026-10-29 零豁免裁:原循环内 `await` 豁免〔2026-10-27〕注销——tune_sim_controller 改 process_frame 信号常驻连接+步进状态机,每帧一局、帧相位逐点对齐;随批申报行为改动一处:运行态收尾由「每局置假」还原为「整批收尾单次置假」,消除与 wd8/ui_tune_probe 断言面的静态矛盾)。
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
这批做什么:把 S13 静态质量闸(gdstyle)在册裸键 `game/presentation/tune_sim_controller.gd|quality/await-in-loop` 真实消除——`run(n)` 的 for 循环内 `await process_frame` 改为 process_frame 信号常驻连接+步进状态机(每帧回调执行一局、步尽次帧收尾断连),`run()` 只留函数级一次 `await _batch_finished` 保持协程身份;改后全文件零 for/while,该键从文本形态根除、此文件对这个键结构性免疫。随批执行两项已裁事项:把「每局置假」还原为「整批收尾单次置假」(已申报行为改动——消除与两个在库断言面的静态矛盾);新增双实现对拍套件,把帧相位等价论证变成当轮真实执行证据。
|
||||
|
||||
什么状态算完:
|
||||
|
||||
1. `tune_sim_controller.gd` 全文件零循环、`await` 仅 `run()` 函数级一处;`python tools/gdstyle_gate.py` 对账该裸键消失(消失键不参与红判定)、无基线外新键。
|
||||
2. 测量语义逐点等价(第 4 节四判据)经双实现对拍在当轮真实跑批中证明——五面对拍全等;wd8 三断言与 ui_tune_probe ⑤ 零改动转绿。
|
||||
3. diff 中已申报行为改动恰一处(收尾置假还原,对照表 V3 行),无第二处行为改动。
|
||||
4. 脚本错误中断路径差异作为声明缺口写入实现报告(禁静默)。
|
||||
5. 批末代码域闸全绿;实现报告与反哺点清单写齐方算收口。
|
||||
|
||||
## 2. 设计事实源
|
||||
|
||||
设计依据唯一出处=`reports/设计-测速循环去await-2026-10-29.md`(2026-10-29 设计闭合,零待裁点):§4 推荐案(process_frame 信号步进状态机伪代码结构)、§5 等价性证明清单(四判据+已声明缺口)、§6 键账预期、§7 行为零变化风险点。架构面凭据=`design/engineering/architecture/architecture.md` v1.25「测试与质量域」S13 测量面豁免注销句(2026-10-29 零豁免裁落文)——豁免注销、行为改动申报面与本卡一致。待办清单条目「零豁免五键清偿批」状态=文档设计已闭合+待写卡(本卡即其中一卡的写卡段产出)。
|
||||
|
||||
## 3. 现状事实(代码级,2026-10-29 实查;开工 T0 按当轮 master 重测重锚——行号基线为本日 master)
|
||||
|
||||
- `game/presentation/tune_sim_controller.gd`(全件 68 行):`run(n)` 在 :36-52——:37 置运行态真、:40-42 开共享 JSONL 日志会话、:43 `panel.set_sim_running(true)`、:44 进度 0/n、:45 建 stats 六键束、:46 取自动策略驱动、:47-50 for 循环体(`_run_one_level` → 进度串 → :50 `await panel.get_tree().process_frame`——命中键的语句)、:51-52 收尾(close_session+报告注入)。`_run_one_level` 在 :56-68(5 参),**尾部两行 :67 `panel.set_sim_running(false)`/:68 `_running = false` 每局执行一次**(潜伏红本体,见下)。类成员 5(db/panel/_base_hp/_driver/_running)+常量 2(:7 SEED_BASE=4200、:8 PlaytestLogger preload);头注 4 行。
|
||||
- 断言面一〔wd8〕`game/tests/unit/presentation/standee_fx_sweep_test.gd:126-134`:FakePanel(内类 Node,:20-40——setter 面并入树供 get_tree)+FakeDriver(:44-55——`run_level` 回调内读 `ctrl.is_running()` 逐局记 `seen`);:129 直构控制器(字典夹具 db)、:131 `await ctrl.run(2)`(run 必须可等待、挂起至整批完成的契约)、:132-134 三断言——`drv.seen == [true, true]`/收尾 `not ctrl.is_running() and not panel.running`/报告非空。套件在 run_all.gd manifest 在册(res://tests/unit/presentation/standee_fx_sweep_test.gd,expect 0)。
|
||||
- 断言面二〔探针 ⑤〕`game/probe/ui_tune_probe.gd:63-83`::65-66 设滑条与 N=10、:67 `press_simulate_for_probe()`(真实按钮 pressed 信号链)、:68-71 守卫环(`while main.debug_overlay.is_running()` 逐帧等——SIM_GUARD_FRAMES=1800 在 :16)、:72-73 预算内未完成判红、:74-83 输出四串断言(关卡完成率/关卡完成剩余 HP 均〔口径换代 V7〕/败北节点/N=10)。面板语义面 `debug_overlay.gd`:`set_sim_running` :81-83 → `_sync_sim_button` :107-110(模拟与两层调试两钮禁用+「模拟中…」文案——浮窗运行态贯穿整批的可见面)、`is_running` :77-79。
|
||||
- 调用面 `game/presentation/main_debug_flow.gd`:`_on_tune_simulate` :72-77——守卫(活跃结算/冒险早退)后 `root._tune_sim.run(n)` **不 await 调用**(返回的协程态丢弃——新形态必须保持此调用形态可用、零改动);`_start_debug_levels` :84 守卫读 `root._tune_sim.is_running()`(两层调试入口互查守卫)。
|
||||
- 静态矛盾推演(设计文档 §2.3——T0 实跑定谳)::67-68 每局执行 → wd8 首局完成即把两个运行态置假 → `drv.seen` 实测 `[true, false]` 必红;探针按下返回后首局已在同一同步段内跑完、运行态已假 → 守卫环立即退出 → 输出停在进度串 → 四串断言全红。推断这两行原在循环之后(「循环体提函数」搬运时被卷入提取体——设计文档 §2.3),wd8 写于 d8 批且当时必绿可反证;两面均不在近期批次的关联档选测覆盖内(套件名与涉案文件无字面关联、probe_gate --full 非恒跑三保险),潜伏红因此未暴露。
|
||||
- 键账:`tools/gdstyle_baseline.txt:15` = 该文件唯一在册键(await-in-loop 裸键,基线 16 键之一)。S13 扫描面=产品码三目录(game/core+data+presentation——probe/sim/tests 不在面,`game/tests/static_scan.sh` S13 头注在案);S8 文件集=九文件显式清单(static_scan.sh :317——不含本件);S9/S10 扫描面同不含 game/tests/。
|
||||
- 产品码 process_frame 订阅面(T0 实查项):本件 :50(循环内 await)+`settlement_fx_view.gd:94`(play_damage_number 内一次性 await 等文本度量——战斗结算呈现期,与模拟批不并存)。现库无「run 途中新增订阅者」场景。
|
||||
- 报告渲染面 `game/presentation/hud_presenter.gd` :197-218 `tune_sim_report`(静态函数,零触碰计划):空数组 `_mean`/`_p90` 双守卫(:221-227/:230-235)、完成率分母 `maxi(1, n)`(:206)——n=0 退化路径渲染安全(本批对拍 n=0 案的前提,实查在案)。
|
||||
- 能力表现状:`game/tests/README.md` 能力表零 tune_sim/调试浮窗行;锚到本批断言宿主套件的唯一既有行=「站桩敌人呈现与结算演出落点」(代表用例 `standee_fx_sweep_test.gd:_init`——wd8 断言所在函数)。
|
||||
|
||||
## 4. 设计契约(违反即返工的红线条款,标 🔴 触碰=L3 停机呈报)
|
||||
|
||||
- 🔴 **测量语义逐点等价**(设计文档 §5 四判据逐条落卡,双实现对拍为当轮执行证据):
|
||||
① 步数与帧数一一对应不变——每局恰占一帧:第 i 局恒在调用点同步段(i=0)或第 i 帧信号发射点(i≥1),收尾恒在第 n 帧发射点,n=0 退化路径两形态同为同步收尾零帧;
|
||||
② 每步工作量与执行相位不变——步进体=同一 `_run_one_level`+同一进度语句;执行点同为 emit process_frame 帧首段(await 恢复点与 connect 回调在引擎内同处一列连接、同一 emit 内被同步调用——设计文档 §4.2 逐步对齐表);
|
||||
③ 终止条件与终止时读数不变——终止=计数走满 n;close_session/运行态复位/报告注入在同帧执行;
|
||||
④ 输出逐字不变——报告=未触碰的 `HudPresenter.tune_sim_report`;stats 是 (种子, atk_pct, hp_pct) 的纯函数、帧时点不进测量值;JSONL 由未触碰的自动策略逐行写、close 时点同帧。
|
||||
违反即返工;等价性对拍失败=L3 停机呈报。
|
||||
- 🔴 **行为改动唯一=收尾置假还原**(已申报——对照表 V3 行):`_run_one_level` 尾部两行(:67-68)删除,运行态复位收进 `_finish_batch()` 收尾单次执行;禁任何其他行为漂移——`_on_tune_simulate` 不加运行态早退守卫(设计文档待裁点 3 备选否决)、发布态零触碰、探针①–④⑥–⑩ 段零触碰、`HudPresenter`/`PlaytestLogger`/`sim/level_autoplay.gd`/`debug_overlay.gd` 零触碰。
|
||||
- 🔴 **脚本错误中断路径差异=声明缺口**(设计文档 §5 缺口 1,接受并文档化):GDScript 无错误陷阱 API、差异不可消除——旧形态步进体内脚本错误=协程死亡静默停摆(运行态永真、报告永不落);新形态=计数未推进、次帧重试同一步(确定性错误逐帧重试,探针 1800 帧守卫可抓;生产态=持续重试的可见坏,与旧「静默卡死」同级不同形)。实现报告文档化义务(T3),禁静默、禁造第三条路(错误陷阱/守卫兜底均已否决);测量批遇错本就整批作废,两形态都不产出可用读数。
|
||||
- 🔴 **S8 结算路径 await 零命中面不触碰**:本件不在 S8 文件集(九文件显式清单实查不含本件);本批零触碰 S8 文件集与一切闸件。
|
||||
- 🔴 **拆分边界纪律**(判据权威=code-conventions §1.1,卡内执行条款):本批零拆出单元——步进状态机收编本件(职责语句与不拆理由见第 8 节);①拆出单元须有可陈述职责语句与单一变化原因;②命不出名字、只能说「剩下的成员」的打包=凑计数袋,禁;③「过阈值」只作发现信号——本批键消除靠形态根除、不靠拆件凑数;④按纪律拆不出内聚单元→停卡呈报;⑤禁沿阈值轴拆。
|
||||
- 🔴 **RNG 与种子零触碰**:SEED_BASE=4200 与逐局种子切分(SEED_BASE+i)零变化——stats 是种子纯函数是等价性论证的前提。
|
||||
- 🔴 **注释纪律**:新增头注/注释零变更叙事(「由 await 改为信号」类句禁——沿革归 git);S11 注释禁词由术语表解析供给,新增注释用白话描述现行形态与信号契约。
|
||||
|
||||
## 5. 范围边界
|
||||
|
||||
做什么:第 3 节四件事——T0 现状定谳(实跑两断言面)、`tune_sim_controller.gd` 步进状态机改造+收尾还原、双实现对拍套件、键账对账与收口。
|
||||
|
||||
不做什么(明示去向):
|
||||
|
||||
- 零豁免其余四键(main.gd 类变量 49、battle_orchestrator 类变量 38、board_cell_unit 30、standee_body 19)——各归组合根注册面批/战斗编排归约批/呈现层状态件批(同条目四卡,待办清单在册)。
|
||||
- `tools/gdstyle_baseline.txt` 禁实现批中途刷新——批末由用户人工重生成(第 6 节)。
|
||||
- `_on_tune_simulate` 运行态早退守卫——不收件(+1 行为面、system_test 前置断言随之需复核,代价大于收益,设计文档待裁点 3 否决)。
|
||||
- `design/` 整个目录、两份根流程清单——实现批禁写;该改的点列反哺点清单。`game/tests/README.md`:测量面专属能力行已随本卡写卡段同批入表(「调参测速批量模拟」行——写卡同批义务,grilling 复核订正),实现批禁写红线不变。
|
||||
- 探针其余段与套件其余断言族(standee_fx_sweep 的 wd2/wd4/wd5/wd12 面)零触碰;`architecture.md` 其余豁免条目(battle_orchestrator 第三条注销句现状化归战斗编排归约批反哺点)零触碰。
|
||||
|
||||
## 6. 关联文档同步面
|
||||
|
||||
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|
||||
|---|---|---|
|
||||
| design/engineering/architecture/architecture.md | 「测试与质量域」S13 测量面豁免注销句(v1.25——「设计闭合、实现批建件」批后现状化;随批申报行为改动句随之成为已实施事实) | 设计权威文档——实现批禁直改;逐条列进 `reports/iter<N>-反哺点-<日期>.md`(豁免注销句现状化),用户裁决后归文档批落文 |
|
||||
| game/tests/README.md | 能力表——测量面专属能力行「调参测速批量模拟(逐帧步进与统计读数)」已随本卡写卡段同批入表(真实入口=批量模拟入口,代表用例=本卡对拍套件);manifest 计数行随套件增减浮动(自助声明,零义务) | 机械面文档——实现批禁写;入表已完成于写卡段(本卡 v1.0 同批),实现期零改动 |
|
||||
| tools/gdstyle_baseline.txt | tune_sim await-in-loop 裸键(:15,该文件唯一在册键)随键消失成死键 | 重生成为人工专用——批末由用户执行 `python tools/gdstyle_gate.py --refresh`(键数 16→15,降幅 <10% 不需 --force);禁实现批中途刷新 |
|
||||
| design/gdd/(全目录) | 无关联文档——测量工具私有机制改造,不改游戏规则与玩家可见行为(tune_sim 全链路发布态不可达,设计文档 §7.3) | 无修订预期;契约句被触碰=停卡呈报走反哺点通道 |
|
||||
|
||||
## 7. 卡前文件结构图(本批新建/修改文件全列)
|
||||
|
||||
| 文件 | 新增/复用 | 职责 | 行为改动 |
|
||||
|---|---|---|---|
|
||||
| game/presentation/tune_sim_controller.gd | 复用(改造) | 批量模拟控制器——process_frame 信号常驻连接+步进状态机;收尾单点 `_finish_batch`;全文件零循环 | 行为改动一处(V3 收尾还原)+结构改形(V1——零漂移由对拍证) |
|
||||
| game/tests/unit/presentation/tune_sim_batch_parity_test.gd | 新增 | 双实现对拍配对套件——遗留 await 形态夹具(内类)+五面对拍断言 | 非行为改动(测试面) |
|
||||
| game/tests/run_all.gd | 复用(改造) | manifest 增一行(新套件注册,expect 0) | 非行为改动(测试基建) |
|
||||
|
||||
结构图与第 8 节互指:新增件一件(对拍套件),其「为什么不能复用/落点唯一」理由见第 8 节;其余两行均为既有文件改造。
|
||||
|
||||
## 8. 落位与可复用性预检
|
||||
|
||||
- **步进状态机不引入新文件(本件内改造)——为什么不拆新件**:单一职责已在件内——`tune_sim_controller` 的职责就是批量模拟控制,步进机制(每帧一局的节律与帧相位承载)是它的私有运行机制,随批生灭(run 期活成员,批末失效下次 run 重写),没有独立于批量模拟的存在意义;拆出「步进机」件命不出独立职责语句=凑计数袋(code-conventions §1.1 判据②④禁)。复用面核查:全仓 grep 无信号步进机同职责实现可复用;其余四形态(SceneTreeTimer 链/Timer 节点/递归协程/线程)已被设计文档 §3 逐一否决(相位不同或键不消)。
|
||||
- **对拍套件落 `game/tests/unit/presentation/` 的唯一性与命名**:落点唯一——与断言宿主 wd8 同目录同协议(extends SceneTree+Kit 收尾),单元层承载;命名 `tune_sim_batch_parity_test.gd`(领域命名、无 ID 前缀);grep 同名与同义标识符实查无第二处。**遗留 await 形态副本全仓只许此一份**——产品码禁留第二实现(旧形态只活在测试夹具内);tests/ 不在 S13/S8/S9/S10 扫描面(扫描面=产品码三目录与 B1 九文件清单,实查在案),夹具内循环 await 合法在册。
|
||||
- **复用面**:夹具的假面板/假驱动复用 wd8 的形态先例(FakePanel/FakeDriver 同形——代码在各套件内自建,不跨套件共享 helper,禁散落);收尾复用 `test_kit.gd` 的 Kit.finish(零断言专用退出码协议)。
|
||||
- **分层与交互**:控制器保持 RefCounted、零 Node 入树;process_frame 连接经 `panel.get_tree()` 取树(与现状同一出口);对拍套件 `--script` 模式零 autoload 依赖(db 用字典夹具,同 wd8 :129 先例);零新增跨层出口、零数值表读取、零随机。
|
||||
|
||||
## 9. 实现规范预算(gdstyle 默认阈值对账:公开方法 ≤20、类变量 ≤15、单函数分支 ≤8、返回 ≤6、参数 ≤5、局部 ≤10、函数 ≤50 行)
|
||||
|
||||
本批零新增产品码文件(改造 `tune_sim_controller.gd` 本件)——改造后该文件键账预期(设计文档 §6 逐规则落卡):
|
||||
|
||||
| 规则 | 预期 | 依据 |
|
||||
|---|---|---|
|
||||
| quality/await-in-loop(裸键,本案标的) | **消除** | 全文件零 for/while;await 仅 `run()` 函数级一处(`await _batch_finished`)——结构性免疫 |
|
||||
| quality/allocation-in-loop | 不命中 | 文件零循环;`PlaytestLogger.new()` 在 run 顶层(现状即如此) |
|
||||
| max-function-length ≤50 | 达标 | run 约 22 行、`_step_frame` 约 12 行、`_run_one_level` 删两行后约 10 行 |
|
||||
| max-branches ≤8 | 达标 | `_step_frame` 一个 if/else;run 一个 if/else |
|
||||
| max-local-variables ≤10 | 达标 | run 局部 3(logger/stats/autoplay——余者转成员);`_step_frame` 局部 1 |
|
||||
| max-returns ≤6 | 达标 | 全 void |
|
||||
| max-parameters ≤5 | 临界持平 | `_run_one_level` 5 参逐字保持;两个新函数 0 参 |
|
||||
| max-class-variables ≤15 | 达标 | 现 5+新增 6=11(`_batch_finished` 信号若被工具计入成员则 12——两值均达标;成员皆 run 期活承载,非凑数袋) |
|
||||
|
||||
存量触面一查:基线实查该文件唯一在册键=await-in-loop 裸键(`tools/gdstyle_baseline.txt:15`)——S13 键较登记值只降不升,裸键消失即清偿;死键由批末用户人工 `--refresh` 自然清去(16→15,降幅 <10% 不需 --force)。新增测试件不在 S13/S9/S10/S8 扫描面(第 3 节实查在案);仍按 test-conventions §6 全类型标注自律(参数/返回值/容器全带标注)。
|
||||
|
||||
## 10. 禁为机检文本保留无效成员(重构类卡必填条款)
|
||||
|
||||
禁止为迎合 S13 机检消息文本(含计数)保留或新增无效成员/别名;本批新增 6 个 run 期活成员皆为 `_step_frame`/`_finish_batch` 读写的承载(`_finished` 若实现期确认零读者,可删——见第 14 节白名单 3,成员 11→10 键账只降不升);机检键与卡片契约互斥时,实现段一律停卡呈报,不得自造第三条路。
|
||||
|
||||
## 11. 任务卡 T0..T3(估时为区间;工作量限制只属迭代层——合计 1–1.5 工作日)
|
||||
|
||||
**T0 现状定谳与读数重锚(0.25 工作日)**
|
||||
|
||||
- [ ] 实跑 wd8 单套件(开发期最窄确认,不作验收凭据):`godot --headless --path game --script res://tests/run_all.gd -- --only=standee_fx_sweep`——记录 :132-134 三断言实况;红=潜伏红定谳成立。套件若因在册无关缺陷先红于 wd8 断言(待办清单「迭代 41 测试债修复」在册的 set_trans 一类),先核该债修复状态、不得借本批顺手修非申报面——读数以「wd8 断言可达性」为准呈报(L2 记录)
|
||||
- [ ] 实跑 ui_tune_probe 单探针:`…console.exe --headless --path game res://probe/ui_tune_probe.tscn`——记录 ⑤ 守卫环与输出四串实况
|
||||
- [ ] 判读:两面按第 3 节静态推演红=前提成立开工;两面实跑全绿=潜伏红证伪=设计前提崩塌——L3 停卡呈报(第 13 节)
|
||||
- [ ] 按当轮 master 重锚第 3 节全部 file:line 与成员计数;漂移处就地改卡并记录
|
||||
- [ ] 实查产品码 process_frame 订阅面——预期两处(本件 :50+settlement_fx_view.gd:94);出现 run 途中新增订阅者场景=L2 记录+代码评审注记(设计文档 §5 缺口 2)
|
||||
|
||||
产出:潜伏红定谳读数(改动前基线证据,独立验收审计要核对);重锚后行号。
|
||||
|
||||
**T1 步进状态机改造(0.25–0.5 工作日)**
|
||||
|
||||
- [ ] `tune_sim_controller.gd` 头注增 `_batch_finished` 信号契约一行(code-conventions §2.1——每信号一行:发射时点=报告注入与运行态复位之后;消费方=run() 自身收尾放行,外部 `await run(n)` 经此放行;现 4 行→5 行;禁变更叙事句)
|
||||
- [ ] 增 `signal _batch_finished` 与 6 个 run 期活成员(名字按设计文档 §4.1 逐字:`_sim_n: int`/`_sim_i: int`/`_sim_stats: Dictionary`/`_sim_autoplay`/`_sim_logger`/`_finished: bool`)
|
||||
- [ ] `run(n)` 改形:setup 段(:37-46 语句逐字保持);n>0 分支——`is_connected` 守卫 connect `panel.get_tree().process_frame`(恰好连接一次,迭代 39 先例)→ `_step_frame()` 首步同步执行(与 await 形态「第 0 局在调用栈内跑完」对齐)→ `await _batch_finished`(函数级单次 await——键消除落点);n=0 分支直调 `_finish_batch()`(循环零进同步收尾,与 await 形态一致不挂起)
|
||||
- [ ] 新增 `_step_frame() -> void`(0 参):`_sim_i < _sim_n` 分支——`_run_one_level(_sim_autoplay, _sim_stats, _sim_i, panel, _sim_logger)`+`panel.set_sim_progress("模拟中:%d/%d …" % [_sim_i + 1, _sim_n])`(串逐字保持现码 :49)+`_sim_i += 1`;else 分支——先 disconnect(防再入)→ `_finish_batch()` → `_batch_finished.emit()`
|
||||
- [ ] 新增 `_finish_batch() -> void`(0 参):`_finished = true` → `close_session()` → `panel.set_sim_running(false)` → `_running = false` → `panel.set_sim_report(HudPresenter.tune_sim_report(_sim_n, panel.atk_pct(), panel.hp_pct(), _sim_stats, _base_hp))`(四语句相对次序按此草图,对两断言面不可观测——白名单 5)
|
||||
- [ ] `_run_one_level` 删尾部两行(:67-68),其余逐字保持(5 参签名不变)
|
||||
- [ ] 孤立验证:`--only=standee_fx_sweep` 全绿(wd8 三断言零改动转绿=潜伏红消除实证)+ui_tune_probe 单探针绿(probe_gate --full 段承载)
|
||||
- [ ] 自检:新增头注/注释零变更叙事、S11 禁词零命中
|
||||
|
||||
取用:T0 重锚行号。产出:`_batch_finished` 信号与 `_step_frame`/`_finish_batch` 签名(T2 对拍新形态即产品码本体);wd8 转绿读数。
|
||||
|
||||
**T2 双实现对拍夹具(0.25–0.5 工作日)**
|
||||
|
||||
- [ ] 建 `game/tests/unit/presentation/tune_sim_batch_parity_test.gd`(extends SceneTree,Kit 收尾,全类型标注):内类 FakePanel(Node——wd8 同形 setter 面,另带进度串/报告记录数组)+FakeDriver(RefCounted——固定返回值两档〔victory/defeat,同 wd8 :53-55 取值〕,零随机;逐局记录帧索引与运行态读数,帧索引经宿主注入的计数 Callable 读取)+AwaitLoopRunner(RefCounted——现 `run()` await 形态逐字副本,含自身 `is_running()` 镜像;**与产品码的申报差异仅两处**:尾部两行按还原语义置收尾、批末把 stats 六键束存夹具成员供对拍读取)
|
||||
- [ ] 对拍驱动:两形态各经 `run(n)` 真实入口驱动(新形态=真 TuneSimScript 直构,旧形态=夹具直构;同参假面板/假驱动各自实例);拓扑钉死——测试宿主先连 process_frame 帧计数、后启动两形态(两形态下「计数先于步进体」相对次序同构,序列可比);n=3 常规+n=0 退化两案
|
||||
- [ ] 五面对拍断言(落点 `_init`,尾缀〔测速 V1〕..〔测速 V5〕):V1 帧索引序列——两形态逐局记录序列逐位相等(每步恰一帧+相位同点的执行证据);V2 运行态序列——驱动内 `is_running()` 读数序列逐位相等+收尾双运行态假相等;V3 进度串序列——面板记录的 set_sim_progress 串序列逐位相等;V4 stats 六键逐位——夹具暴露 stats 与测试内按假驱动固定返回值重算的六键期望(wins/dmg_all/hp_left_win/hp_boss/rounds_all/death_nodes)逐键相等;V5 报告全文逐字——两形态面板记录的 set_sim_report 串逐字相等,n=3 案含「关卡完成率/关卡完成剩余 HP 均/败北节点/N=」渲染面(n=0 案只断逐字相等——空 stats 渲染无剩余 HP 行,`_mean`/`_p90` 空守卫实查在案)
|
||||
- [ ] `run_all.gd` manifest 增行 `{"path": "res://tests/unit/presentation/tune_sim_batch_parity_test.gd", "expect": 0}`
|
||||
- [ ] 孤立验证:`--only=tune_sim_batch_parity` 绿+`--only=standee_fx_sweep` 复跑绿
|
||||
|
||||
取用:T1 的产品码新形态与 `_batch_finished` 放行语义。产出:五面对拍断言面(对照表 V1/V2 行验收主体)。
|
||||
|
||||
**T3 键账对账与收口(0.25 工作日)**
|
||||
|
||||
- [ ] S13 对账:`python tools/gdstyle_gate.py` 输出确认 tune_sim await-in-loop 裸键消失(消失键不参与红判定)、无基线外新键
|
||||
- [ ] 关联档复跑:`--only=standee_fx_sweep,tune_sim_batch_parity`+ui_tune_probe(probe_gate --full 段)全绿
|
||||
- [ ] 批末代码域闸全绿:`tools/run_all_gates.sh --code`(改动含 game/ 下非 .md 行为载体——`--code` 档)
|
||||
- [ ] 错误路径声明缺口写入实现报告(第 4 节 🔴 条全文迁入——禁静默)
|
||||
- [ ] 产出物落位卡:`reports/iter<N>-实现报告-<日期>.md`(各卡状态+实机目检总清单〔本批零目检项〕+遗留读数义务+实现决定记录)与 `reports/iter<N>-反哺点清单-<日期>.md`(第 6 节同步面逐条落点)写齐,方算收口
|
||||
|
||||
编队注记:本卡与零豁免其余三卡无产品码触面交集(本卡触面=tune_sim_controller.gd+game/tests/ 两件);run_all.gd manifest 行与并行批可能交叠——编队归编排段(待办清单条目口径:编队待迭代 42 合回)。
|
||||
|
||||
## 12. 验证闸——改动—验收对照表
|
||||
|
||||
域口径:本批改动全为 `game/` 下非 .md 行为载体——批末跑代码域闸;里程碑步(T 段)出口跑一次全套闸,波内修复只做出红最小单元的最窄确认,新增测试先行孤立验证再并入全套(测试执行两入口铁规不破)。三件保险(冒烟/系统测试/静态扫描)恒跑;02 单元与集成按关联档选套件——**本卡显式申报套件:standee_fx_sweep_test(wd8——套件名与涉案文件无字面关联,diff 推导可能漏选,特此申报)+tune_sim_batch_parity_test(新增)**。测试方式两分法:本批全部调试接口自动化(假驱动/假面板直构+真实按钮信号链探针),零用户目检项(tune_sim 全链路发布态不可达——登记不阻塞条款零登记项)。**静态判据申报(不入对照表,test-conventions §8.4 出口)**:S13 await-in-loop 裸键消除无独立运行期提交面——判据=`python tools/gdstyle_gate.py` 与 `game/tests/static_scan.sh` 退出码(T3 执行),属静态判据+评审注记申报观测面局限;对拍夹具不在 S13/S8/S9/S10 扫描面的声明同此口径(扫描面=产品码三目录与 B1 九文件清单,static_scan.sh 实查在案)。**声明缺口(不入对照表——证明做不出出口)**:脚本错误中断路径差异不可消除,见第 4 节 🔴 条,实现报告文档化(T3)。**能力清单**:本批新增能力一行「调参测速批量模拟(逐帧步进与统计读数)」已随本卡写卡段同批入表(写卡同批义务,grilling 复核订正原「既有名锚定+后续入表」悬置形态)——对照表三行能力列改锚该行;manifest 计数行随套件增减浮动。
|
||||
|
||||
| 行 | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| V1 | 步进状态机改造(循环内 await 消除的落码面) | tune_sim_controller.gd :36-52 改形(run 函数级单次 `await _batch_finished`,全文件零循环)+:56-68 拆出 `_step_frame`/`_finish_batch` | 复用 wd8 驱动形态 `await ctrl.run(2)`(:131——run 协程身份契约,零改动);新增对拍 V4/V5(stats 六键逐位+报告逐字,落点 tune_sim_batch_parity_test.gd:_init,尾缀〔测速 V4/V5〕) | 单元 | TuneSimScript 直构(字典夹具 db+假面板+假驱动,wd8 :129 同款)经 `run(n)` 真实入口;对拍两形态同入口 | run 可等待(await 挂起=整批完成放行)+stats 六键逐位+报告全文逐字 | 新增:调参测速批量模拟(逐帧步进与统计读数) |
|
||||
| V2 | 双实现对拍(帧相位等价的执行化证据) | tune_sim_batch_parity_test.gd 新建+run_all.gd manifest 增行 | 新增五面对拍断言〔测速 V1–V3〕:帧索引序列/运行态序列/进度串序列逐位相等(落点 tune_sim_batch_parity_test.gd:_init) | 单元 | 两形态各经 `run(n)` 真实入口(n=3 常规+n=0 退化);帧索引经测试宿主 process_frame 计数 | 两形态五面记录序列逐位相等(每步恰一帧+相位同点的当轮执行证据——判据本体) | 新增:调参测速批量模拟(逐帧步进与统计读数) |
|
||||
| V3 | 行为改动——收尾置假还原(已申报唯一行为改动) | tune_sim_controller.gd :67-68 删(每局置假)→ `_finish_batch` 收尾单次置假 | 复用 wd8 三断言〔wd8〕(`drv.seen == [true, true]`/收尾 `ctrl.is_running()` 假+`panel.running` 假/报告非空——零改动)+ui_tune_probe ⑤ 守卫环与输出四串(:63-83——零改动) | 单元+探针 | wd8 假驱动回调读 `is_running()`(`await ctrl.run(2)`);探针 `press_simulate_for_probe()` → 按钮 pressed 信号链 → `run(10)` → 守卫环逐帧复查 | 驱动逐局运行态读数序列 [true, true]+收尾双运行态假+守卫环 1800 帧预算内退出+`output_text()` 四关键串(浮窗运行态贯穿整批的可观测提交面) | 新增:调参测速批量模拟(逐帧步进与统计读数) |
|
||||
|
||||
反向核对:diff 中行为改动共一处(V3 行);其余为非行为改动——V1 结构改形(零漂移判据=对拍五面全等+wd8/probe 零改动转绿)、V2 测试面新增、manifest 增行(测试基建)。孤儿断言:对拍五断言挂 V1/V2 两行,无孤儿。
|
||||
|
||||
## 13. 异常分级
|
||||
|
||||
- **L1 自救**:编译错、断言尾缀措辞、夹具记录数组名笔误——就地修复,重跑最窄单元确认。
|
||||
- **L2 记录继续**:T0 套件因在册无关债先红于 wd8 断言(记录可达性事实,不借批顺手修);行号重锚漂移(就地改卡记录);产品码 process_frame 订阅面发现第三处(记录+评审注记——非 run 途中新增场景不红)。
|
||||
- **L3 停机写报告等用户**:①T0 潜伏红证伪——两面实跑全绿=「每局置假系搬运卷入」前提崩塌,停卡退回写卡段重裁行为改动申报面;②等价性对拍失败——五面任一不等=测量语义漂移,设计前提崩塌;③机检预算互斥——改造后实测键超第 9 节预算或基线外新键=上游缺陷停卡退回写卡段(含禁为机检保留无效成员条款冲突);④S13 对账 await 键未消或冒新键;⑤判据绑不上可观测提交面(证明做不出=停卡呈报,禁自造注入破坏或回退取证)。
|
||||
|
||||
## 14. 代拍板白名单(逐条列,超清单记实现报告「实现决定记录」)
|
||||
|
||||
1. 断言失败消息尾缀〔测速 V1–V5〕的分配与措辞。
|
||||
2. 头注 `_batch_finished` 契约行措辞(信号语义与发射时点不变)。
|
||||
3. `_finished` 成员零读者确认后删去(成员 11→10——键账只降不升,行为与断言面零变化)。
|
||||
4. 夹具假面板/假驱动成员命名微调(记录语义不变;与 wd8 同形自建、不跨套件共享)。
|
||||
5. `_finish_batch` 收尾段四语句相对次序按第 11 节 T1 草图次序落码(对两个断言面不可观测——实现期查 git 历史原序可进一步对齐)。
|
||||
6. 排版机械改写(空行、preload 顺序、注释换行)。
|
||||
|
||||
## 15. 待裁点
|
||||
|
||||
零待裁点,开工门=U0。(裁决记录:2026-10-29 用户裁四点——①信号步进状态机形态采纳〔SceneTreeTimer 链/Timer 节点/递归协程/线程四形态淘汰依据见设计文档 §3〕;②收尾置假还原作为已申报行为改动随批实施;③双实现对拍入批;④脚本错误中断路径差异接受并文档化。)
|
||||
|
||||
## 16. 测试削弱申报
|
||||
|
||||
无申报项——wd8 三断言与 ui_tune_probe ⑤ 零改动零削弱;对拍五断言为新增非改判;夹具与产品码的两处申报差异(收尾还原语义+stats 暴露成员)系新增件自身设计、设计文档 §5 在案,非既有断言削弱。禁删断言、禁放宽阈值、禁缩小扫描面、禁把真实入口换成下层直调;未申报的削弱由独立验收审计判红。
|
||||
|
||||
## 17. 独立验收审计
|
||||
|
||||
合并前由未参与实现的会话或子代理执行;报告落 `reports/iter<N>-验收审计-<日期>.md`,未过不得合并。审计至少做五件事:①逐行核对第 12 节对照表(测试存在、真的执行、尾缀可 grep、真实入口未绕过改动点);②抽查判据绑定面——帧索引序列是否真从 process_frame 发射点记录、对拍拓扑两形态是否同构可比、V3 行判据是否钉在运行态提交面而非终态兜底;③核对 T0 定谳证据在案(改动前 wd8/probe 红读数——潜伏红链条完整,缺 T0 读数=审计不过);④核对行为改动唯一性——diff 中除 V3 外无第二处行为改动;⑤检查测试削弱(对照第 16 节零申报)与内部字段直查受控例外(本批零直查——新形态 stats 经报告公开面观测)。
|
||||
|
||||
## 18. MC/数值与 RNG 零触碰声明
|
||||
|
||||
本批零数值改动、零数据表改动、零 RNG 流变化:SEED_BASE=4200 与逐局种子切分零变化(stats 种子纯函数前提);对拍夹具零随机(假驱动固定返回值)。MC 对拍不跑、零跑批义务(无数值改动——`sim-data/README.md` 档位硬闸:无数值改动零跑)。
|
||||
@@ -0,0 +1,337 @@
|
||||
# 需求卡片——组合根注册面批(main.gd 类变量归 15:界面注册面+三域句柄容器)
|
||||
|
||||
状态行:v1.0 定稿——零待裁点(2026-10-29 用户裁:注册面拓扑一门面+三域容器、合同机器迁入、别名消灭清单整体确认;实现层细目授权 agent 按设计文档执行)
|
||||
|
||||
接收方:待办清单条目「零豁免五键清偿批——S13 余量五键真修四卡(2026-10-29 登记,来源=会话提及)」——本卡为其四卡之首(组合根注册面批)。
|
||||
|
||||
来源:reports/设计-组合根注册面-2026-10-29.md(2026-10-29 设计闭合,**唯一事实源**);architecture 权威=design/engineering/architecture/architecture.md v1.25(2026-10-29——「模块归属·呈现层」表 ui_registry 行、「呈现层装配与会话生命周期」节屏成员寻址迁注册面句=原 S13 豁免登记注销、RunScope 节)。
|
||||
|
||||
## 1. 目标与完成定义
|
||||
|
||||
这批做什么:把 main.gd(组合根)里散着的屏壳、覆盖层一级句柄与视觉层合同表收进一个「界面注册面」——一个不挂树的 RefCounted 门面件(ui_registry.gd)加三个按领域分的句柄容器(ui_screens/ui_battle/ui_modals),探针和系统测试对界面元素的引用从 `main.X` 一级地址改成 `main.ui.<域容器>.<句柄>` 三段式地址。同时消灭 7 个探针兼容别名/转发成员、退役 6 个 main 纯转发模态方法。main.gd 类变量从 49 降到 15,S13 基线键真实还债,architecture 在册的 S13 豁免登记随批注销。
|
||||
|
||||
**行为零变化**:装配序、信号接线、层序(树序=登记序=z 序)、RunScope 会话生命周期、RNG 消费序全部零变化;探针断言只换地址、不换判据。
|
||||
|
||||
完成定义(全部满足才算完):
|
||||
1. 五闸主证全绿——probe_gate 默认段+`--click`+`--full`、render_gate golden 零差异、run_smoke、run_system_test、run_all 02 单元与集成(main.gd 触组合根=横切面,按 AGENTS.md 关联档口径回落全部套件)。
|
||||
2. static_scan 过——四新文件零新基线键(S9 全类型标注、S10 头注);main.gd 类变量实测 15(键账对账批末申报,基线 refresh 由用户发令)。
|
||||
3. 改址完整性自检——按 49 名逐名 grep,`game/` 下旧一级路径 `main.<旧名>`/`root.<旧名>`/`self.<旧名>` 残留=0,报告留档。
|
||||
4. 产出物落 `reports/`——实现报告、反哺点清单、验收审计报告(独立审计未过不合并)。
|
||||
|
||||
**编队注记与估时**:本卡与「战斗编排归约批」(battle_orchestrator 拆 RoundCycle/BattleFacts 两件——architecture v1.25 轴丁设计闭合、待写卡)和「测速循环批」(tune_sim_controller 步进状态机——architecture v1.25 S13 测量面豁免注销设计闭合、待写卡)同代待编排;三批无同文件交叠(本批触面=main.gd+main_ui_build+三流程件+探针/测试面)。与迭代 42(在飞:gdstyle 尾波清偿批+level_runner 商店委托层拆除)**存在文件交叠**——并排卡「level_runner 商店委托层拆除」触面含 main.gd(1 处)、main_adventure_flow(6 处)、main_overlay_flow(2 处),全在本批触面集内(grilling 复核证伪原「无交叠」声明,订正);**本批开工前置=迭代 42 合回 master**,T0 按合回点重测改址计数。另与「呈现层状态件批」共享 ui_input_probe.gd 触面(本批改 main.X 地址面、该批改四处 u.face.* 读面)——同代编排时禁并行、先后皆可。估时区间 **3–4 个工作日**(设计文档 §8),低于迭代冻结线(5 个工作日),可编批;编入哪个迭代由迭代编排段定。
|
||||
|
||||
## 2. 现状事实
|
||||
|
||||
全部行号为 **2026-10-29 实查——本批编入在 gdstyle 尾波补件批相关迭代之前/之后均须 T0 按 T0 时点 master 重测重锚**。
|
||||
|
||||
1. `game/presentation/main.gd`(915 行)共 **49 个类变量**(逐名清点 main.gd:61–148,含 3 个委托属性);S13 基线键 `game/presentation/main.gd|quality/max-class-variables = 49`(阈值 15)在 tools/gdstyle_baseline.txt 在册,architecture v1.25 在册 S13 豁免登记〔2026-10-27「组合根类变量面即探针契约面」〕已随 v1.25 注销、待本批真实还债。
|
||||
2. 视觉层合同机器四样全在 main.gd:`LAYER_CONTRACT` 常量(main.gd:39–59,19 项含 host/shell/tags 标注)、`_apply_layer_contract()`(main.gd:254–279,全仓唯一 move_child 落位点)、`_layer_node(key)`(main.gd:227–248,19 键 match)、`_register_modal(m, tags)`(main.gd:218–224,anchors preset+flow.register)。
|
||||
3. 探针兼容别名/接缝成员 7 个:`board_view`(main.gd:95)、`ap_bar`(main.gd:96)——赋值点 main_ui_build.gd:48–49;`_modals`(main.gd:129,赋值 main_ui_build.gd:245);`_row_queue`(main.gd:111–113,委托属性读 `_row_pacer.pending_rows()`);`_seed_edit`(main.gd:74,赋值 main_ui_build.gd:208);`_settlement_stop_pending`(main.gd:134–143,读=is_armed()/写=arm()/disarm());`_deferred_modal`(main.gd:148–150,读 `_modal_flow._deferred`)。
|
||||
4. main 纯转发模态方法 6 个:`_open_modal_after_playback`(main.gd:156–158)、`_on_pump_ended`(main.gd:161–163)、`_open_modal`(main.gd:282–284)、`_close_modal`(main.gd:285–287)、`_on_modal_closed`(main.gd:288–290)、`_input_locked`(main.gd:292–295)——各自一行转呼 `_modal_flow` 真方法。另有一个纯转发方法同批退役:`_flush_row_queue`(main.gd:516,一行转呼 `_row_pacer.flush`)——`_row_pacer` 句柄迁 ui.screens 后调用方 `pacing_queue_test.gd:103` 改调 `main.ui.screens.row_pacer.flush()`(表 D 归宿行)。
|
||||
5. 装配承接件 main_ui_build.gd:`build(root)` 八步(main_ui_build.gd:21–29),赋值目标全走 `root.X` 一级成员(main_ui_build.gd:38–51 等);`pump_ended` 注入点 main_ui_build.gd:62;context 束注入 `open_modal/close_modal`(main_ui_build.gd:144、168);`_apply_layer_contract()` 末位调用 main_ui_build.gd:247。
|
||||
6. 消费面引用量(设计文档 §0 机械统计,T0 实跑重计):探针+系统测试 `main.X` 成员引用约 **867 处**;四个流程承接件(main_adventure_flow/main_overlay_flow/main_debug_flow/main_ui_build)`root.X` 引用约 200–350 处(设计文档 §0 与 §3.2 两处统计口径不一,以 T0 映射表脚本实跑计数为准)。抽查实证:ui_input_probe.gd:34–43(seed_edit/level_screen)、system_test.gd:94–109(LAYER_CONTRACT、_layer_node、V2 句柄等价五连比)、smoke_boot.gd:68–75(`main.get()` 6 处)、pacing_queue_test.gd:108/132/147/149(`_row_queue` 3 处+`board_view` 1 处)、source_guard_test.gd:69–77(V1d 层序单口断言,现扫 main.gd 单文件)、theme_projection_test.gd:724–725(V6 断言 main.gd 含 `debug_overlay.diagnose_requested.connect(_on_diagnose_pressed)` 串)。
|
||||
7. 留 main 的 14 成员(对账见表 B)全部是组合根自身状态、组合根拆件引用、autoload 读视图;`run_scope` 引用(探针约 173 处)零迁移。
|
||||
8. 探针段构成(architecture「测试与质量域」probe_gate 行):默认段 ui_input_probe/ui_struct_probe/layout_probe/ui_contrast_probe/screen_flow_probe,`--click` 加 ui_click_probe,`--full` 加 ui_probe/ui_tune_probe/t17_defer_probe/fx_probe。
|
||||
9. meta_progression_forge_test 经 `load("res://presentation/main.gd")` 直呼 static `build_adventure_params`——留 main,零迁移(main.gd:366–376)。
|
||||
10. 本批不涉 RNG/数值/存档触面;PARITY 触面(battle_orchestrator.gd)不在 diff,无 MC 义务。
|
||||
|
||||
## 3. 设计契约(违反即返工,标 🔴 触碰=L3 停机呈报)
|
||||
|
||||
- 🔴 **行为零变化**:装配序与 add_child 顺序、信号连接语句逐条不变;层序合同表条目、顺序、tags、host/shell 标注**逐字零变化**只换宿主文件;`_begin_session`/闲时会话/整节点 queue_free 机制一字不动;RNG 消费序零触碰;呈现层订阅禁令与核心写调用唯一出口纪律零触碰。
|
||||
- 🔴 **探针断言语义零变化**:改址只换地址不换判据——断言条件、尾缀(既有〔装配生命批 V1〕〔装配生命批 V3〕等保留)、消息语义不动;禁借改址删断言、放宽阈值、缩小扫描面。
|
||||
- 🔴 **拆分边界纪律五条**(判据权威=code-conventions §1.1,此处写红线不复制定义):①每个拆出单元须有可陈述的职责语句与单一变化原因(四件各一句,见 §12 表,实现报告逐件一行承载);②拆出单元须有集体身份——命不出名字、只能说「剩下的成员」的打包=凑计数袋,禁;③「过阈值(49→15)」只许作发现信号,作拆分或收拢动机即违规;④按纪律拆不出内聚单元→停卡呈报走豁免通道,禁硬拆凑绿;⑤禁保留/新增无效成员与别名凑数——本批方向是净消灭(7 成员+6 方法),实现期发现任何「为保地址兼容」新增的转发壳即违契约。
|
||||
- 🔴 **禁为机检文本保留无效成员**:禁止为迎合机检消息文本(含计数)而保留或新增无效成员/别名;机检键与本卡契约互斥时(如实测出新基线键 NEW 红)一律停卡呈报,不得自造第三条路(详见 §13 条款节)。
|
||||
- 🔴 **测试削弱申报制**:允许改动的旧断言全集见 §8「测试削弱申报」,未申报的删改由独立验收审计判红。
|
||||
|
||||
## 4. 范围边界
|
||||
|
||||
做:ui_registry+三域容器建件;合同机器四样迁驻;main.gd 49→15 改形;main_ui_build 与三流程件改址;探针九件+probe_ui_util+smoke_boot+system_test+pacing_queue_test 改址;V1d/V6 源码断言重锚;七别名与六转发方法消灭。
|
||||
|
||||
不做(明示去向):
|
||||
1. architecture.md 直改——实现批禁写 `design/`,ui_registry 行现状化与 main_ui_build 行层序句改指走反哺点通道(§6)。
|
||||
2. game/tests/README.md 改动——实现批禁写;写卡段义务已核=零增删零改行(§6)。
|
||||
3. modal_stack.gd/modal_flow.gd 语义改动——两件零触碰,本批只改它们的消费方地址。
|
||||
4. RunScope/会话生命周期机制、row_pacer 排播时序、T17 挂起编排——零触碰。
|
||||
5. S13 豁免登记第二/三条(tune_sim_controller、battle_orchestrator)——原文不动,归「战斗编排归约批」「测速循环批」。
|
||||
6. board_cell_unit/standee_body/board_view 悬停域等结构债——归迭代 42 尾波清偿批,不收件。
|
||||
7. 基线 refresh——`python tools/gdstyle_gate.py --refresh` 由用户发令人工跑(净减 1 键,低于 10% 骤降守卫,无需 --force);实现批只做键账对账申报。
|
||||
8. MC/数值验证——无数值改动零跑。
|
||||
|
||||
## 5. 关联文档同步面
|
||||
|
||||
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|
||||
|---|---|---|
|
||||
| design/engineering/architecture/architecture.md(设计权威——实现批禁直改) | ①「模块归属·呈现层」ui_registry 行现登记「实现批建件」态,实现后应现状化;②同表 main_ui_build 行「层序逻辑不在此件——唯一事实源仍是 `main.LAYER_CONTRACT` + `_apply_layer_contract()`」句在实现后失效(唯一事实源迁 ui_registry.LAYER_CONTRACT+ui.apply_layer_contract());③「呈现层装配与会话生命周期」节屏成员寻址迁注册面句 v1.25 已落、实现后核对措辞与实况一致 | 反哺点通道:把上列 ①②③ 逐条列进 `reports/iter<N>-反哺点-<日期>.md`(改哪一节、改成什么、依据=设计文档 §3.3 建议句),用户在会话中裁决后归文档批落文 |
|
||||
| game/tests/README.md(机械面——实现批禁写) | 本批零新增能力(改址只换地址,能力集不变);受影响存量行核对:「模态覆盖层编排与输入锁」行真实入口(ModalFlow 两个公开方法)与代表用例(modal_flow_test.gd:_init 等)不变;「结算明细带逐行呈现与排播节奏」行代表用例 pacing_queue_test.gd:_init 不变(`文件:函数` 锚不受成员改址影响) | 写卡段义务已当场核完=**零增行、零删行、零改行**;批末收尾只核对表上名字与实际落地一致(改名则回表) |
|
||||
| design/gdd/ 无关联文档 | 行为零变化,任何系统文档陈述不受影响;层序唯一事实源属 architecture 不属 GDD | 无(本行占位——按规约查不出也要写明) |
|
||||
|
||||
## 6. 卡前文件结构图(本批新建/修改文件全列)
|
||||
|
||||
| 文件 | 职责 | 新增/复用 | 行为改动? |
|
||||
|---|---|---|---|
|
||||
| game/presentation/ui_registry.gd | 界面注册面门面:三容器属性+LAYER_CONTRACT+node(key) 合同寻址+apply_layer_contract(root) 唯一落位口 | 新增(预检 §12) | 非行为改动(新建件承载既有合同——落点变化,对照表行 1/2) |
|
||||
| game/presentation/ui_screens.gd | 屏壳与全屏容器域句柄册(9 成员) | 新增(预检 §12) | 非行为改动(对照表行 3) |
|
||||
| game/presentation/ui_battle.gd | 战区视图域句柄册(5 成员) | 新增(预检 §12) | 非行为改动(对照表行 3/4) |
|
||||
| game/presentation/ui_modals.gd | 模态层域句柄册+ModalFlow 持有+register_layer(14 成员) | 新增(预检 §12) | 非行为改动(对照表行 3/7) |
|
||||
| game/presentation/main.gd | 组合根改形:49→15;合同机器与转发方法迁出;内部取址改 ui.*;头注追加注册面句 | 修改 | 非行为改动(纯结构——装配/接线/层序/RNG 零变化,四闸主证;对照表行 2/6/7) |
|
||||
| game/presentation/main_ui_build.gd | 八步赋值目标改 root.ui.*;context 束与 pump_ended 注入改址;_seed_edit/_modals 赋值行退役 | 修改 | 非行为改动(八步顺序/add_child 序/连接语句逐条不变;对照表行 3) |
|
||||
| game/presentation/main_adventure_flow.gd/main_overlay_flow.gd/main_debug_flow.gd | root.X 同表映射(模态口改指 root.ui.modals.flow;句柄读改 root.ui.*) | 修改 | 非行为改动(对照表行 3/7) |
|
||||
| game/probe/ 九探针+probe_ui_util.gd(凡 T0 映射表命中的 main.X 引用件) | 旧地址→main.ui.* 机械改写 | 修改 | 非行为改动(断言语义零变化;对照表行 4/6) |
|
||||
| game/tests/smoke_boot.gd | get() 键改址(4 改 2 留) | 修改 | 非行为改动(对照表行 3) |
|
||||
| game/tests/system_test.gd | main.X 改址(V1a/V1c/V2 句柄等价/V3 矩阵取址两处) | 修改 | 非行为改动(判据零变化;对照表行 1/5) |
|
||||
| game/tests/unit/contracts/source_guard_test.gd | V1d 重锚(单文件扫描→全目录扫描,判据强化) | 修改 | 非行为改动(断言改写已申报;对照表行 8) |
|
||||
| game/tests/unit/presentation/theme_projection_test.gd | V6 断言串改新连接串 | 修改 | 非行为改动(断言改写已申报;对照表行 9) |
|
||||
| game/tests/unit/presentation/pacing_queue_test.gd | board_view/_row_queue 改址(3+1 处) | 修改 | 非行为改动(对照表行 6) |
|
||||
|
||||
不触碰:modal_flow.gd/modal_stack.gd/row_pacer.gd/ui_assembler.gd/run_scope.gd/meta_progression_forge_test.gd(static 入口零迁移)/全部 core 与 data。
|
||||
|
||||
## 7. 任务卡 T0..T4
|
||||
|
||||
### 7.1 地址契约(全批唯一映射依据——表 A/B/C/D 与设计文档 §1.2 对账表同源)
|
||||
|
||||
**表 A:迁入注册面的 28 个 main 成员**(容器内成员名去下划线=公共地址面):
|
||||
|
||||
| 现成员(2026-10-29 行号) | 新地址 | 现成员 | 新地址 |
|
||||
|---|---|---|---|
|
||||
| `_menu_screen`(:100) | ui.screens.menu_screen | `legend_overlay`(:116) | ui.modals.legend_overlay |
|
||||
| `_camp_screen`(:101) | ui.screens.camp_screen | `node_overlay`(:117) | ui.modals.node_overlay |
|
||||
| `_adventure_screen`(:102) | ui.screens.adventure_screen | `level_screen`(:83) | ui.modals.level_screen |
|
||||
| `_start_overlay`(:79) | ui.screens.start_overlay | `curio_overlay`(:78) | ui.modals.curio_overlay |
|
||||
| `_battle_root`(:84) | ui.screens.battle_root | `_end_overlay`(:80) | ui.modals.end_overlay |
|
||||
| `_inter_overlay`(:81) | ui.screens.inter_overlay | `shop_overlay`(:118) | ui.modals.shop_overlay |
|
||||
| `_inter_label`(:82) | ui.screens.inter_label | `camp_overlay`(:119) | ui.modals.camp_overlay |
|
||||
| `debug_badge`(:126) | ui.screens.debug_badge | `settings_overlay`(:121) | ui.modals.settings_overlay |
|
||||
| `_row_pacer`(:105) | ui.screens.row_pacer | `status_panel`(:122) | ui.modals.status_panel |
|
||||
| `stage`(:91) | ui.battle.stage | `career_overlay`(:123) | ui.modals.career_overlay |
|
||||
| `log_view`(:92) | ui.battle.log_view | `save_select_overlay`(:124) | ui.modals.save_select_overlay |
|
||||
| `info_panel`(:93) | ui.battle.info_panel | `confirm_dialog`(:75) | ui.modals.confirm_dialog |
|
||||
| `board_zone`(:94) | ui.battle.board_zone | `debug_overlay`(:125) | ui.modals.debug_overlay |
|
||||
| `settlement_fx`(:97) | ui.battle.settlement_fx | `_modal_flow`(:128) | ui.modals.flow |
|
||||
|
||||
**表 B:留 main 的 14+1**:db、run_scope、save_manager、meta、settings_store、logger、_debug_entry、_confirm_consumer、_confirm_consumer_slot、_debug、_treasure_ui、_bonus、_camp_pres、_tune_sim(保留理由逐个=组合根自身状态/拆件引用/autoload 读视图,见设计文档 §1.2 第二表)+新增 `ui: UiRegistry`。改后 15,恰在阈内。
|
||||
|
||||
**表 C:消灭的 7 个别名/接缝成员**:
|
||||
|
||||
| 成员 | 本体 | 消灭后地址 |
|
||||
|---|---|---|
|
||||
| board_view(:95) | =board_zone.board_view | ui.battle.board_zone.board_view |
|
||||
| ap_bar(:96) | =board_zone.ap_bar | ui.battle.board_zone.ap_bar |
|
||||
| _modals(:129) | =_modal_flow.stack | ui.modals.flow.stack |
|
||||
| _row_queue(:111) | 委托属性=_row_pacer.pending_rows() | ui.screens.row_pacer.pending_rows()(同一 Array 引用,语义不变) |
|
||||
| _seed_edit(:74) | =debug_overlay.seed_edit | ui.modals.debug_overlay.seed_edit.text(main._seed_value 唯一消费点) |
|
||||
| _settlement_stop_pending(:134) | 委托属性读=is_armed()写=arm()/disarm() | run_scope.settlement_stop_timer 直呼同名面 |
|
||||
| _deferred_modal(:148) | 委托属性=_modal_flow._deferred | ui.modals.flow._deferred |
|
||||
|
||||
**表 D:方法/函数级改址**:
|
||||
|
||||
| 旧地址 | 新地址 | 消费方 |
|
||||
|---|---|---|
|
||||
| main._layer_node(key) | main.ui.node(key) | system_test V1c(实查 source 点 system_test.gd:97;设计文档记 3 处——T0 重计) |
|
||||
| main._register_modal(m, tags) | ui_modals.register_layer(m, tags)(逐字迁入:anchors preset+flow.register) | 仅 _apply_layer_contract 内部消费,随迁 |
|
||||
| main._apply_layer_contract() | main.ui.apply_layer_contract(root)(root 作参传入,main_ui_build.gd:247 调用点改) | 装配尾唯一调用点 |
|
||||
| main._open_modal(m) | main.ui.modals.flow.open(m) | 探针各 1 处+流程件 root. 共约 23 处(T0 重计);main 内部调用点(_on_confirm_accepted 等)同改 |
|
||||
| main._close_modal(m)/main._on_modal_closed(m) | main.ui.modals.flow.close(m)(信号 bind 目标 main_ui_build.gd:99/209 改 flow.close.bind) | 同上 |
|
||||
| main._input_locked() | main.ui.modals.flow.locks_input() | 探针 18 处(T0 重计)+main._on_board_action/_on_stop_pressed/_on_refresh_confirmed 内部 |
|
||||
| main._open_modal_after_playback(m) | main.ui.modals.flow.open_after_playback(m) | 流程件 root. 2 处+探针(T0 重计) |
|
||||
| main._on_pump_ended | main.ui.modals.flow.pump_ended | row_pacer.pump_ended 注入点 main_ui_build.gd:62 |
|
||||
| smoke_boot `main.get("_start_overlay"/"debug_badge"/"legend_overlay"/"status_panel")` | `main.get("ui").<域>.<名′>`(get 只解析一层,后续走公共字段) | smoke_boot.gd:70/73/74/75;`get("run_scope")`/`get("settings_store")` 零迁移 |
|
||||
| source_guard V1d 串 | 重锚:扫全 `game/presentation/*.gd`,`move_child(` 只允许出现在 ui_registry.gd 的 apply_layer_contract 函数体内(从扫单文件变扫全目录——判据强化) | source_guard_test.gd:69–77 |
|
||||
| main._flush_row_queue() | main.ui.screens.row_pacer.flush()(转发壳随 `_row_pacer` 迁移退役) | pacing_queue_test.gd:103 |
|
||||
| theme_projection V6 串 | 改断言新串 `ui.modals.debug_overlay.diagnose_requested.connect(_on_diagnose_pressed)`(连接语句本体随 T2 改写 main.gd:209) | theme_projection_test.gd:724–725 |
|
||||
|
||||
### 7.2 新件接口块(T1 定义,T2 起逐字取用;类型标注义务=S9 过)
|
||||
|
||||
```
|
||||
# game/presentation/ui_registry.gd —— 界面注册面(RefCounted,不挂树,零信号连接,零会话期引用)
|
||||
class_name UiRegistry
|
||||
extends RefCounted
|
||||
const ModalStack := preload("res://presentation/modal_stack.gd")
|
||||
const LAYER_CONTRACT: Array[Dictionary] = [ …main.gd:39-59 内容逐字迁入,一项不增不减不改… ]
|
||||
var screens: UiScreens
|
||||
var battle: UiBattle
|
||||
var modals: UiModals
|
||||
func node(key: String) -> Node # 合同寻址:_layer_node 的 19 键 match 逐字迁入
|
||||
func apply_layer_contract(root: Control) -> void # 落位算法逐字搬运(move_child 单口;登记经 modals.register_layer)
|
||||
|
||||
# game/presentation/ui_screens.gd —— 屏壳与全屏容器域(RefCounted,纯字段无方法)
|
||||
class_name UiScreens
|
||||
extends RefCounted
|
||||
var menu_screen: Control
|
||||
var camp_screen: Control
|
||||
var adventure_screen: Control
|
||||
var start_overlay: Control
|
||||
var battle_root: Control
|
||||
var inter_overlay: Control
|
||||
var inter_label: Label
|
||||
var debug_badge: Button
|
||||
var row_pacer: RowPacer # 经 preload 常量取型(res://presentation/row_pacer.gd 非 class_name 全局)
|
||||
|
||||
# game/presentation/ui_battle.gd —— 战区视图域(RefCounted,纯字段无方法)
|
||||
class_name UiBattle
|
||||
extends RefCounted
|
||||
var stage: BattleStageView
|
||||
var log_view: BattleLogView
|
||||
var info_panel: HeroInfoPanelView
|
||||
var board_zone: BoardZoneView
|
||||
var settlement_fx: SettlementFxView
|
||||
|
||||
# game/presentation/ui_modals.gd —— 模态层域(RefCounted)
|
||||
class_name UiModals
|
||||
extends RefCounted
|
||||
var flow: ModalFlow
|
||||
var legend_overlay: LegendOverlay
|
||||
var node_overlay: NodeOverlay
|
||||
var level_screen: LevelMapScreen
|
||||
var curio_overlay: CurioPickOverlay
|
||||
var end_overlay: BattleEndOverlay
|
||||
var shop_overlay: ShopOverlay
|
||||
var camp_overlay: CampOverlay
|
||||
var settings_overlay: SettingsOverlay
|
||||
var status_panel: StatusPanel
|
||||
var career_overlay: CareerOverlay
|
||||
var save_select_overlay: SaveSelectOverlay
|
||||
var confirm_dialog: ConfirmDialog
|
||||
var debug_overlay: DebugOverlay
|
||||
func register_layer(m: Control, tags: Array = []) -> void # _register_modal 逐字迁入
|
||||
```
|
||||
|
||||
(main.gd 现有类型标注逐字沿用:ui_battle/ui_modals 十八句柄的类型名=main.gd:78–125 在用全局类名;ui_screens 三屏壳标 Control,若 T1 实测场景根基类不符,按代拍板白名单第 6 条取实际基类。)
|
||||
|
||||
### 7.3 T0——读数重锚与对账(估时 0.5 个工作日)
|
||||
|
||||
- [ ] 按 T0 时点 master 重测重锚本卡全部行号与计数:main.gd 类变量实数(gdstyle 读数)、合同机器四样行位、七别名与六转发方法行位、六转发方法的全部调用点清单(main 内部+流程件+探针+system_test 分文件计数)。
|
||||
- [ ] 49 成员逐一对账:对照本卡表 A/B/C 逐名核对仍在位、仍归该档(迁移 28/留 14/消灭 7)——任何一名对不上=L3 停卡呈报(设计文档 §1.2 对账表为第二依据)。
|
||||
- [ ] 映射表脚本生成+对账:探针九件+probe_ui_util+smoke_boot+system_test+四流程件的 `main.X`/`root.X` 全量计数与旧→新映射(机械生成+人工复核语义位——属性读写约 750 处、方法调用四类、字符串键 6 处、源码断言 2 条);设计文档 867/350/200 三处统计口径以本次实跑为准并在实现报告记数。
|
||||
- [ ] 未登记源码断言排查:grep `presentation/main.gd` 于 game/tests+game/probe 全部源码断言面——只许 V1d/V6 两条命中;新发现=L3 停卡补申报,禁自行改判。
|
||||
- [ ] 迁移函数对账:查 tools/gdstyle_baseline.txt 中 main.gd 的 `_apply_layer_contract`/`_layer_node`/`_register_modal` 源函数键——branches/returns/函数长有超默认登记值的,迁移即拆函数(拆分不改语义)。
|
||||
- [ ] 孤立验证(改前基线读数):`python tools/gdstyle_gate.py`(采集 main.gd=49 读数)+`godot --headless --path game --script res://tests/run_all.gd -- --only=source_guard`(绿)。
|
||||
- 取用:本卡 §7.1 四表。产出:重锚后的映射表与对账表(实现报告附件节,T2/T3/T4 消费)。
|
||||
|
||||
### 7.4 T1——注册面与三域容器建件(估时 1 个工作日)
|
||||
|
||||
- [ ] 按 §7.2 接口块建 ui_registry.gd:LAYER_CONTRACT 自 main.gd:39–59 逐字迁入(ModalStack 常量引用随迁);`node(key)` 19 键 match 逐字;`apply_layer_contract(root)` 落位算法逐字搬运(move_child 单口语义不变)。
|
||||
- [ ] 建 ui_screens/ui_battle/ui_modals(成员与类型按 §7.2;ui_modals.register_layer 自 main.gd:218–224 逐字迁入);四件全类型标注、`_init` 不收参(容器由门面构造)。
|
||||
- [ ] 四件 class_name(UiRegistry/UiScreens/UiBattle/UiModals)+跑一次编辑器扫描刷新全局类缓存+同步 .uid(code-conventions 语言纪律 5——T2 main.gd 类型标注 UiRegistry 在 --script 模式可解析的前置);文件头 `##` 注释介绍模块(禁变更叙事、禁文档反向链接)。
|
||||
- [ ] 孤立验证:`game/tests/static_scan.sh`(S9 四新件零红+S10 头注过+S13 四新件零新键)+`godot --headless --path game --script res://tests/run_all.gd -- --only=source_guard`(V8 全库扫描仍绿——新件零字符串 Callable)。
|
||||
- 取用:T0 映射表。产出:四件公开面(UiRegistry.new()/.screens/.battle/.modals/.node(key)/.apply_layer_contract(root)/modals.register_layer(m, tags)——T2 逐字消费)。
|
||||
|
||||
### 7.5 T2——main.gd 改形与装配/流程件改址(估时 1–1.5 个工作日)
|
||||
|
||||
- [ ] main.gd 新增 `var ui: UiRegistry`;`_ready` 在 `_build_ui()` 之前 `ui = UiRegistry.new()`(容器随门面构造;装配在 _ready 建闲时会话之前完成——时序零变化)。
|
||||
- [ ] 表 A 28 成员迁出:main 内部全部取址同步改 `ui.*`(含 main.gd:199–200 启动态两行、_seed_value:911、_on_confirm_accepted/_start_adventure/_resume_from_menu/_replay_locked_click 等内部调用点改指 ui.modals.flow.*/ui.screens.row_pacer.pending_rows());合同机器四样自 main 删除(随 T1 迁驻)。
|
||||
- [ ] main_ui_build.gd:八步赋值目标改 `root.ui.<域>.<名′>`(八步顺序、add_child 顺序、连接语句逐条不变);`root._seed_edit` 赋值行(:208)删除;`pump_ended` 注入改 `root.ui.modals.flow.pump_ended`(:62);`root._modals` 赋值行(:245)保留至 T4;context 束 overlay/toast/start_overlay/board_view 键值改址(:137–147、:163–169,注入时点与值不变);`_apply_layer_contract` 调用改 `root.ui.apply_layer_contract(root)`(:247)。
|
||||
- [ ] 三流程件 root.X 按表 A/D 同表映射(root._open_modal/_close_modal/_open_modal_after_playback/_input_locked → root.ui.modals.flow.*;`_settlement_stop_pending` 写点改 `run_scope.settlement_stop_timer.arm()/disarm()`——写点计数 T0 对账)。
|
||||
- [ ] smoke_boot.gd get() 改址(4 改 2 留,§7.1 表 D)。
|
||||
- [ ] source_guard_test.gd V1d 重锚为全目录扫描(尾缀〔注册面 V1〕);theme_projection_test.gd V6 改断言新串(尾缀〔注册面 V2〕)——两条改写即 §8 申报的测试改动全集。
|
||||
- [ ] 孤立验证:`python tools/run_smoke.py`(冒烟绿=装配链完整)+`godot --headless --path game --script res://tests/run_all.gd -- --only=source_guard,theme_projection,meta_progression_forge`(三套件绿——V1d/V6 重锚后绿、static 入口零变化)+`python tools/gdstyle_gate.py`(main.gd 类变量读数记录——此轮含 7 别名=22,基线键 49 内不红,读数进实现报告)。系统测试与探针此轮预期红(消费面未改址——T3 收口),不构成本卡验证面。
|
||||
- 取用:T1 四件公开面。产出:main.ui.* 地址面全量生效的组合根(T3 消费)。
|
||||
|
||||
### 7.6 T3——探针/系统测试/单元批量改址(估时 1 个工作日)
|
||||
|
||||
- [ ] 探针九件+probe_ui_util 按 T0 映射表机械改写:属性读/写改 `main.ui.<域>.<名′>`;四类方法调用按表 D;`var bv = main.board_view` 型局部承接改 `var bv = main.ui.battle.board_zone.board_view`(每文件 1–2 处)。
|
||||
- [ ] 接缝三件:ui_struct_probe 的 `main._modals` → `main.ui.modals.flow.stack`(登记序断言);t17_defer_probe 的 `main._deferred_modal` → `main.ui.modals.flow._deferred`(挂起态断言);ui_click_probe 的 `_settlement_stop_pending` 读点 → `main.run_scope.settlement_stop_timer.is_armed()`。
|
||||
- [ ] system_test.gd 改址:V1c 的 `main.LAYER_CONTRACT`→`main.ui.LAYER_CONTRACT`、`main._layer_node`→`main.ui.node`;V2 句柄等价断言(:107–109)改 ui 地址(等价语义不变:ui.battle.board_zone.board_view == ui.screens.adventure_screen.board_view 型);V1a 候选清单与全件 main.X 逐表映射;V3 矩阵 `_face_snapshot` 的 `main._modal_flow`→`main.ui.modals.flow`、`main._row_pacer`→`main.ui.screens.row_pacer`(其余四持件取址不变)。
|
||||
- [ ] pacing_queue_test.gd:`main.board_view`→`main.ui.battle.board_zone.board_view`(:132);`main._row_queue`→`main.ui.screens.row_pacer.pending_rows()`(:108/:147/:149,实查 3 处)。
|
||||
- [ ] 改址完整性自检:映射表驱动 49 名逐名 grep——`game/` 下(探针/tests/流程件/main 自身)旧一级路径 `main.<旧名>`/`root.<旧名>`/`self.<旧名>` 残留=0,报告留档(实现报告对照表挂行)。
|
||||
- [ ] 孤立验证:`tools/probe_gate.sh --click --full`(全段退出码 0)+`python tools/run_system_test.py`(V1–V9 摘要 0 失败)+`python tools/run_smoke.py`+`godot --headless --path game --script res://tests/run_all.gd -- --only=pacing_queue,source_guard`。
|
||||
- 取用:T2 地址面。产出:全部消费面新地址(T4 前提——别名/转发方法零消费方)。
|
||||
|
||||
### 7.7 T4——别名与转发方法消灭+批末收口(估时 0.5–1 个工作日)
|
||||
|
||||
- [ ] 删 main.gd 七别名/接缝成员(表 C——此点已零消费方)与六转发方法(§2 第 4 条清单);删 main_ui_build.gd:245 `root._modals` 赋值行;main.gd 类变量终态 **15**。
|
||||
- [ ] 文件头注随迁改写:main.gd 头注追加一句「界面句柄与层清单在 ui 注册面(ui_registry.gd)」;main_ui_build.gd 头注「层序唯一事实源」句改指 ui_registry(指址改写、词面语义不变)。
|
||||
- [ ] 逐卡扫尾孤立验证:`tools/render_gate.sh`(golden 零差异)+`tools/probe_gate.sh --click --full`+`python tools/run_smoke.py`+`python tools/run_system_test.py`+`godot --headless --path game --script res://tests/run_all.gd -- --only=pacing_queue,modal_flow,source_guard,theme_projection,meta_progression_forge`。
|
||||
- [ ] 批末全量:`tools/run_all_gates.sh --code` 全绿(main.gd 触组合根=横切面——02 单元与集成按 AGENTS.md 横切面口径回落全部套件;冒烟/系统测试/静态扫描三件保险恒跑)。里程碑步出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试先行孤立验证再并入全套。
|
||||
- [ ] S13 键账对账申报:main.gd 键 49→15 只降不升、四新件零新键;基线 refresh 由用户发令人工跑(--refresh,净减 1 键低于骤降守卫)。
|
||||
- [ ] **产出物落位卡**(轻闸全绿后、合并前写齐,方算收口):`reports/iter<N>-实现报告-<日期>.md`——各卡状态+实机目检总清单(登记不阻塞:注册面改址后实机过一遍三屏切换与模态开合)+遗留读数义务(基线 refresh)+实现决定记录+改址计数与 grep 自检留档;`reports/iter<N>-反哺点-<日期>.md`——§5 同步面所列 architecture 三条逐条有落点;`reports/iter<N>-验收审计-<日期>.md`——独立验收审计(未参与实现的会话或子代理执行,未过不得合并)。
|
||||
- 取用:T3 零消费方清单。产出:终态 main.gd(15 var)+三份 reports/ 产出物。
|
||||
|
||||
## 8. 验证闸(改动—验收对照表)
|
||||
|
||||
本批全部改动为**非行为改动**(结构与地址重构):每行判断依据=改前改后在同一输入上行为一致,由探针/系统测试/冒烟/渲染 golden 四闸主证(真实入口全绿),静态 grep 只作完整性辅证。调试接口/目检两分法:本批无新玩法能力,验证全走自动化载体;用户目检仅一条登记项(T4 实机过三屏与模态开合),登记不阻塞。**静态判据申报(不入对照表,test-conventions §8.4 出口——grilling 复核订正)**:S13 键账对账(main.gd 实测 15、四新件零新键、基线 refresh 由用户发令)与映射表驱动 grep 残留=0 自检无独立运行期提交面——判据=`python tools/gdstyle_gate.py`/`game/tests/static_scan.sh` 退出码与 T3 grep 自检留档,属静态判据+评审注记申报观测面局限;对照表行 2/11 只承载其运行面回归与全量闸半边。
|
||||
|
||||
| # | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 1 | 注册面建件+合同机器迁驻(层序零变化) | 新建 ui_registry.gd(LAYER_CONTRACT main.gd:39–59 逐字迁入);ui_screens/ui_battle/ui_modals 建件 | 系统测试 V1c「合同树序链逐对保序」(system_test.gd:94–106 改址 main.ui.LAYER_CONTRACT/main.ui.node,尾缀〔装配生命批 V1〕保留) | 系统测试 | `python tools/run_system_test.py` | 运行期树序逐对保序=LAYER_CONTRACT 序(get_index 链——层序零变化的运行期提交面) | 既有:模态覆盖层编排与输入锁 |
|
||||
| 2 | main.gd 改形回归(49→15 结构改形) | main.gd:61–148 改形(28 迁出+7 消灭+1 新增);六转发方法退役 | 批末 run_smoke+run_system_test 双宿主摘要 0 失败(改形回归主证;S13 键账静态判据见域口径申报) | 冒烟+系统测试 | `python tools/run_smoke.py`;`python tools/run_system_test.py` | 双宿主摘要 0 失败(改形后全链路回归面) | 既有:模态覆盖层编排与输入锁 |
|
||||
| 3 | 装配与流程件改址(root.ui.*) | main_ui_build.gd 八步赋值目标;三流程件+context 束+pump_ended 注入点;smoke_boot.gd:70/73/74/75 | 冒烟主屏存活面六断言(smoke_boot.gd:64–75 改址后全绿)+系统测试 V2「组合根句柄指向屏壳成员」等价断言(system_test.gd:107–109 改址,五连比同指) | 冒烟+系统测试 | `python tools/run_smoke.py`;`python tools/run_system_test.py` | 启动态装配句柄在座且等价断言两侧同指一对象(多一跳取到同一引用) | 既有:模态覆盖层编排与输入锁 |
|
||||
| 4 | 探针面批量改址(约 867 处) | 探针九件+probe_ui_util 旧地址→main.ui.*(只换地址不换判据) | probe_gate 全段退出码 0(ui_input_probe 全 case/ui_struct_probe/layout_probe/ui_contrast_probe/screen_flow_probe+--click ui_click_probe+--full ui_probe/ui_tune_probe/t17_defer_probe/fx_probe) | 探针 | `tools/probe_gate.sh --click --full`(单件形态:`godot --headless --path game res://probe/ui_input_probe.tscn` 等) | 探针经新地址取到同一节点并驱动真实输入路径(改址完整性的第一消费方主证) | 既有:棋盘悬停反馈(三语义光标/目标格边框/路径预览点迹) |
|
||||
| 5 | 系统测试面改址+RunScope 生命周期零变化 | system_test.gd main.X 改址;V3 矩阵取址两处(_modal_flow→main.ui.modals.flow、_row_pacer→main.ui.screens.row_pacer) | 系统测试 V1–V9 全绿(含 V3a–V3i 九阶段×五引用面矩阵,尾缀〔装配生命批 V3〕保留) | 系统测试 | `python tools/run_system_test.py` | 第五引用面逐面同源比对(回调悬挂=红——存活性矩阵判据零变化) | 既有:模态覆盖层编排与输入锁 |
|
||||
| 6 | 别名/接缝成员消灭(7 个) | main.gd:74/95/96/111/129/134/148 消灭;消费方改址(pacing_queue_test.gd:108/132/147/149、ui_struct_probe、t17_defer_probe、ui_click_probe、main 自身 4 处 _row_queue) | run_all 选跑 pacing_queue 绿(排空零分叉/零丢行/延迟双态/会话清队断言改址后判据不变)+ui_struct_probe 登记序断言+t17_defer_probe 挂起态断言 | 单元+探针 | `godot --headless --path game --script res://tests/run_all.gd -- --only=pacing_queue`;`tools/probe_gate.sh --full` | 属性链与别名取到同一对象引用(断言逐条等价——同一 Array/同一节点的可观测面) | 既有:结算明细带逐行呈现与排播节奏 |
|
||||
| 7 | 六个 main 纯转发模态方法退役 | main.gd:156/161/282/285/288/292 退役;调用方改指 ui.modals.flow 五个真方法+注入点 main_ui_build.gd:62 | modal_flow 单元套件绿+系统测试 V3g 模态开合段+ui_click_probe 模态开合路径 | 单元+系统测试+探针 | `godot --headless --path game --script res://tests/run_all.gd -- --only=modal_flow`;`python tools/run_system_test.py`;`tools/probe_gate.sh --click` | 经真方法开合编排(遮挡互斥/锁谓词/挂起兜底行为面零变化——开合后可见性与锁态提交面) | 既有:模态覆盖层编排与输入锁 |
|
||||
| 8 | V1d 源码断言重锚 | source_guard_test.gd:69–77 重锚为全目录扫描(move_child 只许在 ui_registry.gd apply_layer_contract 体内) | 「V1d 层序落位单口」重锚断言,尾缀〔注册面 V1〕 | 单元 | `godot --headless --path game --script res://tests/run_all.gd -- --only=source_guard` | 源码契约扫描面(扫描面>0 前置——全 presentation 目录零第二落位点) | 既有:模态覆盖层编排与输入锁 |
|
||||
| 9 | V6 源码断言改串 | theme_projection_test.gd:724–725 改断言新连接串 | 「V6 转储入口连接随迁」新串断言,尾缀〔注册面 V2〕 | 单元 | `godot --headless --path game --script res://tests/run_all.gd -- --only=theme_projection` | main.gd 源码含新连接串(同一连接的宿主面改写) | 既有:UI 全局主题与按钮五态(含对比度锚) |
|
||||
| 10 | 视觉零变化主证 | 全批呈现层地址重构(像素面零改动) | render_gate golden 零差异(shot_probe 七屏+菜单 golden+棋盘 golden) | 探针/golden | `tools/render_gate.sh` | 截图与基线图逐像素容差零差异(视觉零变化的独立主证——出现任何此前不存在的差异即 L3) | 既有:站桩敌人呈现与结算演出落点 |
|
||||
| 11 | 改址完整性收口 | 全批改址面(49 名逐名) | 批末代码域闸全绿(`tools/run_all_gates.sh --code`,02 横切面回落全量套件);映射表驱动 grep 自检=T3 步骤义务(静态判据,见域口径申报) | 全量闸 | `tools/run_all_gates.sh --code` | 所选域全绿回执 | 既有:模态覆盖层编排与输入锁 |
|
||||
|
||||
**测试削弱申报**(实现期允许的旧断言改动全集,超出即审计判红):
|
||||
1. V1d:扫描面从「main.gd 单文件」扩为「全 game/presentation/*.gd」——判据强化,非削弱。
|
||||
2. V6:断言串从 main.gd 旧连接串改为新连接串——同一连接的宿主面改写,断言不删除。
|
||||
3. 冒烟/系统测试/探针/pacing 各断言:只改地址字面,判据与既有尾缀不动——零删除、零放宽、零换下层直调。
|
||||
4. 七别名+六转发方法随批退役=test-conventions §5.5 同生死条款的执行:消费方断言已全部改指新地址,旧地址无断言残留(T3 grep 自检为证)。
|
||||
|
||||
**独立验收审计**:入口与报告=`reports/iter<N>-验收审计-<日期>.md`;审计方=未参与实现的会话或子代理,逐行核对对照表、抽查判据绑定面、检查测试削弱、核对静态判据行的观测面局限注记;未过不得合并。
|
||||
|
||||
## 9. 异常分级
|
||||
|
||||
- **L1 自救**:单点漏改址→grep 定位补改后重跑该闸段;`--only` 选跑零命中(用法错 exit 2)→修正选词重跑;探针段超时→孤立复跑该段定位。
|
||||
- **L2 记录继续**:同一红闸连续 3 次同因→升级记录并在实现报告「实现决定记录」节记因后继续最窄确认。
|
||||
- **L3 停机写报告等用户**:
|
||||
1. **行为零变化契约触探**——任一闸出现改前不存在的红且定位为层序/时序/接线行为变化;render golden 出现任何此前不存在的差异。
|
||||
2. **机检预算互斥=上游缺陷停卡退回写卡段**——四新件或 main 终态实测超 §14 预算、或 static_scan 出基线外 NEW 红键;禁开豁免、禁自造第三条路。
|
||||
3. T0 对账失败——49 名逐一对账与表 A/B/C 任一名对不上,或发现未登记的 main.gd 源码字符串断言。
|
||||
4. 拆分边界④触发——按纪律拆不出内聚单元(本设计已拆出,若实现期发现表 A 归档错误的成员强行迁入会破集体身份时适用)。
|
||||
|
||||
## 10. 代拍板白名单(逐条列,超清单记实现报告「实现决定记录」)
|
||||
|
||||
1. 改址机械改写:映射表内旧→新地址的行内改写、被改行注释内旧地址字面同步更新(判据不动)。
|
||||
2. 重锚断言的消息文字措辞(V1d/V6 两条——尾缀〔注册面 V1〕〔注册面 V2〕与判据不变)。
|
||||
3. 迁移函数/成员头注按新宿主改写指址(词面随迁、语义不改)。
|
||||
4. 探针内局部承接变量名保留或内联(`var bv` 型——判据不变)。
|
||||
5. grep 自检留档在实现报告内的节名与格式。
|
||||
6. ui_screens 三屏壳句柄静态类型在 Control 与实测场景根实际基类之间取(判据=S9 过+赋值编译过;成员名与地址面不变)。
|
||||
7. main 内部调用点在 T2 先改真方法、转发方法留至 T4 删除的批内中间态时序(终态零转发壳)。
|
||||
|
||||
## 11. 待裁点
|
||||
|
||||
**零待裁点,开工门=U0。** 设计文档 §8 五项待裁点已于 2026-10-29 用户全裁:①注册面拓扑=一门面+三域容器;②合同机器随批迁入注册面;③七别名消灭+六转发方法退役+容器内成员去下划线——清单整体确认;④run_all 关联档口径=main.gd 触组合根按横切面回落全部套件;⑤编批归迭代编排段定(本卡估时 3–4 个工作日在冻结线内)。
|
||||
|
||||
## 12. 落位与可复用性预检
|
||||
|
||||
**复用面**(逐个排除既有件——为什么不能复用):
|
||||
- **modal_flow.gd(ModalFlow)**:模态编排纯逻辑——开合编排、输入锁谓词、T17 挂起。它管行为不管地址;注册面管「元素清单、层序、寻址」,是它的宿主容器(flow 挂在 ui_modals 里)。职责语句不同,不能拿它当注册面。
|
||||
- **modal_stack.gd(ModalStack)**:登记册数据结构(遮挡记账),被 ModalFlow 持有;层序合同表与三域寻址不归它。非候选。
|
||||
- **ui_assembler.gd**:无态静态装配工厂——装配期造控件用完即弃,不持任何句柄;注册面是随 main 常驻的句柄容器。把「造」和「持」并进一件会让静态工厂变有态,破坏现行职责。
|
||||
- **run_scope.gd**:局态节点——装的是会话状态不是界面元素清单;173 处探针引用零迁移义务已核。非候选。
|
||||
- 形态先例(非复用对象):ConfigDB 迭代 41 三张域容器(config_domain_combat/run/crossrun.gd)解决过同构的成员数超标问题——本批三容器即同一形态在呈现层的落法。
|
||||
|
||||
**唯一面**:层序合同唯一事实源随迁 ui_registry.LAYER_CONTRACT(main.gd 侧删除,不双写);合同寻址唯一口=ui_registry.node();模态登记唯一口=ui_modals.register_layer()。2026-10-29 实查 game/presentation/ 下无 ui_registry/ui_screens/ui_battle/ui_modals 同名或同义件(architecture v1.25 登记「实现批建件」即此四名,盘上未建)——新增无第二落点。
|
||||
|
||||
**分层与交互面**(调用路径显式):
|
||||
- 读地址路径:views/探针/流程件 → `main.ui.<域容器>.<句柄>` → 容器字段 → 节点。三段式每段有领域含义(组合根→注册面→域→元素),与 ConfigDB 的 `db.<域容器>.<成员>` 两段式同构。
|
||||
- 注册面禁反向持有:不持 main、不持 run_scope、零信号连接、零核心写调用、零 `_process`——依赖单向(views→信号→组合根→core)零触碰;组合根单点装配不变(信号连接仍在组合根与 main_ui_build)。
|
||||
- 构造路径:main._ready 建 `ui = UiRegistry.new()`(门面自建三容器),main_ui_build 八步向容器登记;四件全 RefCounted 不挂树(节点本体树位与 add_child 归属零变化——row_pacer 仍 add_child 到 main,注册面只持引用)。
|
||||
- Core 零 UI 红线零触碰:本批改动全部在 game/presentation/ 与测试面。
|
||||
|
||||
## 13. 禁为机检文本保留无效成员(重构类卡必填条款)
|
||||
|
||||
禁止为迎合机检消息文本(含计数)而保留或新增无效成员/别名:main.gd 终态 15 个类变量必须个个有 §7.1 表 B 的职责理由,禁留空占位或替身成员凑计数;四新件的字段必须个个是表 A 在册句柄或 flow,禁加「以防万一」的空槽。机检键与本卡契约互斥时(如实测出新基线键 NEW 红、或键账与申报不符),实现段一律停卡呈报走 L3,不得自造第三条路。判据权威=code-conventions §1.1⑤。
|
||||
|
||||
## 14. 实现规范预算(gdstyle 默认阈值:公开方法 ≤20、类变量 ≤15、单函数分支 ≤8、返回 ≤6)
|
||||
|
||||
| 新件 | 公开方法 | 类变量 | 阈值判定 |
|
||||
|---|---|---|---|
|
||||
| ui_registry.gd | 2(node/apply_layer_contract) | 3(三容器属性;LAYER_CONTRACT 为常量不占 var) | 双达 |
|
||||
| ui_screens.gd | 0 | 9 | 双达 |
|
||||
| ui_battle.gd | 0 | 5 | 双达 |
|
||||
| ui_modals.gd | 1(register_layer) | 14(13 句柄+flow) | 双达(余量 1——第 14 个模态句柄出现即触发拆分审视,作发现信号用) |
|
||||
|
||||
- 迁移函数对账:`_apply_layer_contract`/`_layer_node`/`_register_modal` 自 main.gd 迁入,T0 查 gdstyle_baseline.txt 源函数键——超默认登记值的迁移即拆函数(拆分不改语义);node(key) 的 19 键 match 与合同落位循环预期在默认分支阈内(设计文档 §7 同判断),实测出新键=基线外 NEW 红=L3 停卡(禁开豁免)。
|
||||
- 存量触面一查:本批触碰的 presentation 存量件(main.gd/main_ui_build.gd/三流程件)预期「S13 键较登记值只降不升」——main.gd 49→15;main_ui_build 与三流程件零成员变化(仅语句内地址改写);达成手段=表 A/C 全量迁移+别名净消灭。
|
||||
- 指标例外申报:无(本批不需要任何超默认面;main.gd 改后 15 在阈内,S13 豁免登记注销后不留新例外)。
|
||||
|
||||
## 15. 源码级断言与探针契约面的随批义务(防漏项清单)
|
||||
|
||||
1. V1d(source_guard_test.gd:69–77)与 V6(theme_projection_test.gd:724–725)随批重锚——本卡已全量排查 main.gd 源码断言面仅此两条(T0 复核义务不豁免)。
|
||||
2. 探针段覆盖义务:probe_gate 必须 `--click`+`--full` 全跑——ui_click_probe 是最大改址户,只跑默认段会漏最深的改址面。
|
||||
3. 冒烟 V1 族 get() 键、系统测试 V1c/V2/V3 取址、pacing `_row_queue` 三处——都在 §7.1 表 D 与 T3 清单内,T0 映射表生成后逐条打钩对账。
|
||||
+3
-1
@@ -75,8 +75,10 @@
|
||||
| 迭代 39 | 已完成(2026-10-27) | 已退役(git 历史可考) | 2026-10-26 | ≈10.15 个工作日〔用户特批 2026-10-26 超 10 个工作日〕 | 已退役(git 历史可考) |
|
||||
| 迭代 40 | 已完成(2026-10-28) | 已退役(git 历史可考) | 2026-10-27 | ≈6.375 个工作日 | 已退役(git 历史可考) |
|
||||
| 迭代 41 | 已完成(2026-10-29) | 已退役(git 历史可考) | 2026-10-27 | ≈13.15 个工作日〔用户特批 2026-10-27 超 10 个工作日〕 | 已退役(git 历史可考) |
|
||||
| 迭代 42 | 待开工 | reports/需求卡片-gdstyle尾波清偿批-2026-10-29.md<br>reports/需求卡片-level_runner商店委托层拆除-2026-10-29.md | 2026-10-29 | ≈5.375 个工作日 | — |
|
||||
| 迭代 42 | 进行中 | reports/需求卡片-gdstyle尾波清偿批-2026-10-29.md<br>reports/需求卡片-level_runner商店委托层拆除-2026-10-29.md | 2026-10-29 | ≈5.375 个工作日 | — |
|
||||
| 迭代 43 | 待开工 | reports/需求卡片-战斗一屏样张批-2026-10-28.md | 2026-10-29 | ≈6.5 个工作日 | — |
|
||||
| 迭代 44 | 待开工 | reports/需求卡片-组合根注册面批-2026-10-29.md<br>reports/需求卡片-战斗编排归约批-2026-10-29.md<br>reports/需求卡片-测速循环批-2026-10-29.md | 2026-10-29 | ≈7.875 个工作日 | — |
|
||||
| 迭代 45 | 待开工 | reports/需求卡片-呈现层状态件批-2026-10-29.md<br>reports/需求卡片-gdstyle尾波补件批-2026-10-29.md | 2026-10-29 | ≈7 个工作日 | — |
|
||||
|
||||
- 迭代 38 收口为带红合并〔用户特批 2026-10-26〕:09 静态扫描 S13 gdstyle 恶化 2 条经批准记入基线存量红(git 提交 c4c69701),卡② 停卡退上游,处方已于 2026-10-26 修订定稿 v1.3(git 提交 b3ea7532),随「gdstyle 存量债全量清偿」条目波 7 待编排。
|
||||
- 迭代 39 收口为带红合并〔用户特批 2026-10-27〕:02 EV 锚 goblin 0.9148∉[1.00,1.20](触发器批有意行为改动,fp f74b9a48ef4a)已随 EV 锚重锚批换带归绿(git 提交 ba5105aa);08d 生涯.md:55 行号漂移已随 2026-10-28 批后收尾反哺落文修复归绿。三卡拆分后终局 gdstyle 恶化 2 条(battle_orchestrator max-file-length、level_map_screen max-class-variables)归迭代 40 卡①还债与迭代 41 存量债序列。
|
||||
|
||||
@@ -59,9 +59,9 @@
|
||||
|
||||
**状态**:待执行
|
||||
|
||||
#### 迭代 41 测试债修复——9 个套件失败与静态扫描三项红(2026-10-29 登记,来源=批次移交)
|
||||
#### 闸基线 02/09 两键换代——存量红指纹已随迭代 41 测试债批归绿(2026-10-29 登记,来源=批次移交)
|
||||
|
||||
**实况**:证据=能力审计上电批(worktree 分支 `capgate-20261029`,提交 48e6e551)全量闸复跑,首次实测迭代 41 两卡合回(合并提交 eb9bb537,测试特许移交+直接合回,见 roadmap 收口注脚)后的代码面真实状态:①02 单元与集成测试 9 套件失败——`config_db_test`(`if` 块内声明的变量在块外引用,解析错误)、`config_db_fatal_oob_test`(退出码 2≠期望 1)、`table_structure_guard_test`(`_TreeSaveMock` 缺 `meta_state`)、`treasure_items_test`(`StubDB` 缺 `crossrun`)、`standee_fx_sweep_test`(`set_trans` 空引用)、`forge_workbench_test`(120 秒超时挂死)、`tree_requires_level_test`(`row_by_id` 在空基址)、`save_manager_domain_test`(缺 `_migrate_legacy_save`)、`theme_projection_test`(`CampOverlay` 缺 `_recent_list`);②09 静态扫描红项清单与基线不一致——S9 类型闸 24 处(迭代 41 拆出的新件缺 `# type-hint: ignore` 注解与参数类型)、S10 文件头 4 处(`config_db` 与三个域容器头注日期)、S11 注释禁用词 1 处(`adventure_table.gd:55`),而 gdstyle 与 S13 已随迭代 41 还清(基线两条存量红已过期,须随修复实测重生成)。本条目只修测试与注解债、不改游戏行为。本批合入经用户 2026-10-29 裁带红合并:能力审计上电批只动闸件与规约(代码域零新增红),代码域现存红全部由本条目承接。**2026-10-29 用户裁(「表结构版本」数值冲突甲案+孤儿常量可删)**:文档侧已随文档域直改落地——数据配置.md 删「表结构版本」调参行、依赖表与验收项中的版本常量表述,存档序列化.md 迁移链「表结构版本对齐」改「随表结构变化」,architecture.md 两处常量名改现役 `SAVE_FORMAT_VERSION`;代码侧 `game/core/config_db.gd` 的死常量 `SCHEMA_VERSION`(全仓零引用,值为 1,与文档原载 2 无对应)随本批删除。
|
||||
**实况**:证据=迭代 41 测试债批代码域闸实测(worktree 分支 `testdebt-20261029`,回执 commit afd1a41f、域=code、scope=full、零新增红),02 单元与集成与 09 静态扫描两闸判「基线红 → 现绿(改善)」;基线 `game/tests/.gates/baseline.json` 里这两键仍记着已消除的存量红指纹(02 fp f9865f1a5a44=9 套件失败;09 fp 1a9ad773489f=S9 24 处+S10 4 处+S11 1 处),留着不动的后果=日后同类红回归会被判「存量红·对基线零新增」静默放行。待做=两键按归绿实测重生成(写 exit=0/绿指纹),改的是 `game/` 下非 .md 文件=代码面,须随下一个代码批在 worktree 内一并落、禁主区直改;人工确认凭据=上述回执与 reports/迭代41测试债批-实现报告-2026-10-29.md 第三节。本条目无设计段(机械重锚),不走写卡与编排。
|
||||
|
||||
**改动面**:游戏代码
|
||||
|
||||
@@ -69,12 +69,36 @@
|
||||
|
||||
#### gdstyle 尾波清偿批——基线余量 11 键定向整改(2026-10-29 登记,来源=审计发现)
|
||||
|
||||
**实况**:证据=`tools/gdstyle_baseline.txt`(2026-10-29 人工重锚后余量 16 键)+reports/审计-gdstyle存量债清点与清偿方案-2026-10-26.md(§三波次方案与 §六文档设计段裁定记录,裁定全部继续有效)。迭代 39/40/41 三批清偿后余 16 键:本批承接 11 键——board_view 6(_paint_cell 长度 139/分支 24/局部 22、循环内 new、类变量 32、公开方法 27)/level_runner 3(公开方法 50、类变量 30、_enter_node 返回 7)/battle_orchestrator 文件长 1035/adventure_runner 类变量 28;另 5 键走豁免通道另行讨论不在本批(main.gd 类变量 49、tune_sim_controller 循环内 await、board_cell_unit 类变量 30、standee_body 类变量 19、battle_orchestrator 类变量 38——其中三条已有架构豁免登记)。需求卡片 v2.0 定稿(零待裁点):reports/需求卡片-gdstyle尾波清偿批-2026-10-29.md 设计段裁决 2026-10-29 用户裁闭合(D1 装板域拆新件 BoardInstaller 两修正·architecture v1.24 轴丙已落文/D2 悬停域不拆/D3 商店域候选 A/D4 断点域不拆/D5 五降值键豁免终局/D6 商店域并排编队——执行合同=并排卡「level_runner 商店委托层拆除」v1.1,本卡不重复执行),零待裁点。预期两档:归绿 6 键(_paint_cell×3、循环内 new、_enter_node、文件长);豁免终局 5 键(board_view 32/27、level_runner 50→33/30、adventure 28——批末按实测值落 architecture 豁免登记,键 7 实测值视并排卡时序)。本卡估时 3–4.25 工作日(并排卡 ≈1.5 工作日另计)。MC/数值零触碰(结构整改不改数值与 RNG 消费序);battle_orchestrator 触 PARITY_TOUCH_FACES——实跑对拍须经用户批准、不得借机重锚。S13 键账对账在批末,基线重锚由用户发令人工 --refresh(预期降幅逾 10% 须 --force)。
|
||||
**实况**:证据=`tools/gdstyle_baseline.txt`(2026-10-29 人工重锚后余量 16 键)+reports/审计-gdstyle存量债清点与清偿方案-2026-10-26.md(§三波次方案与 §六文档设计段裁定记录,裁定全部继续有效)。迭代 39/40/41 三批清偿后余 16 键:本批承接 11 键——board_view 6(_paint_cell 长度 139/分支 24/局部 22、循环内 new、类变量 32、公开方法 27)/level_runner 3(公开方法 50、类变量 30、_enter_node 返回 7)/battle_orchestrator 文件长 1035/adventure_runner 类变量 28;另 5 键走豁免通道另行讨论不在本批(main.gd 类变量 49、tune_sim_controller 循环内 await、board_cell_unit 类变量 30、standee_body 类变量 19、battle_orchestrator 类变量 38——其中三条已有架构豁免登记)。需求卡片 v2.0 定稿(零待裁点):reports/需求卡片-gdstyle尾波清偿批-2026-10-29.md 设计段裁决 2026-10-29 用户裁闭合(D1 装板域拆新件 BoardInstaller 两修正·architecture v1.24 轴丙已落文/D2 悬停域不拆/D3 商店域候选 A/D4 断点域不拆/D5 五降值键豁免终局/D6 商店域并排编队——执行合同=并排卡「level_runner 商店委托层拆除」v1.1,本卡不重复执行),零待裁点。预期两档:归绿 6 键(_paint_cell×3、循环内 new、_enter_node、文件长);豁免终局 5 键(board_view 32/27、level_runner 50→33/30、adventure 28——批末按实测值落 architecture 豁免登记,键 7 实测值视并排卡时序)。本卡估时 3–4.25 工作日(并排卡 ≈1.5 工作日另计)。MC/数值零触碰(结构整改不改数值与 RNG 消费序);battle_orchestrator 触 PARITY_TOUCH_FACES——实跑对拍须经用户批准、不得借机重锚。S13 键账对账在批末,基线重锚由用户发令人工 --refresh(预期降幅逾 10% 须 --force)。2026-10-29 用户再裁(零豁免延伸):D5 五降值键改留债——本卡批末「落 architecture 豁免登记」步骤**不执行**(键留基线冻结禁恶化、不落豁免登记);D2 悬停域与 D4 断点域改判拆件,由新条目「gdstyle 尾波补件批」承接(需求卡片已写),本卡对应任务不施工。
|
||||
|
||||
**改动面**:游戏代码
|
||||
|
||||
**状态**:文档设计已闭合+已写卡+已编迭代 42
|
||||
|
||||
#### gdstyle 尾波补件批——悬停域与断点域拆件(2026-10-29 登记,来源=会话提及)
|
||||
|
||||
**实况**:尾波卡 v2.0 裁去的 D2/D4 两拆件项经用户再裁恢复(2026-10-29,零豁免延伸+D5 留债)。设计闭合凭据=architecture.md v1.25(呈现层表 board_hover 行/核心层表 breakpoint_store 行/「冒险域拆分」节随动句)。需求卡片:reports/需求卡片-gdstyle尾波补件批-2026-10-29.md(v1.0 定稿零待裁点)。范围:board_view 拆 board_hover(11 函数族+2 成员,`_r0` 留宿主)+adventure_runner 拆 breakpoint_store(6 成员+`BREAKPOINT_FIELDS` 27 键冻结函数族,`resume_adventure` 留宿主薄壳)。键账预期:board_view 类变量 32→约30、公开方法 27 持平、adventure_runner 类变量 28→约22——三键**留债**(键留基线冻结禁恶化、禁落豁免登记)。编队:待迭代 42 合回后编入;与呈现层状态件批同代时其先行(u.st 写入面改型后 hover 拆件在新面上施工)。估时 2.5–3.5 工作日。
|
||||
|
||||
**改动面**:游戏代码
|
||||
|
||||
**状态**:文档设计已闭合+已写卡+已编迭代 45
|
||||
|
||||
#### 零豁免五键清偿批——S13 余量五键真修四卡(2026-10-29 登记,来源=会话提及)
|
||||
|
||||
**实况**:用户 2026-10-29 裁「不允许任何豁免」——S13 三条豁免注销(architecture.md v1.25 落文),五键真实修复至阈值内:main.gd 类变量 49→15(组合根注册面:ui_registry 一门面+三域容器,约 867 处探针/系统测试引用改址 `main.ui.<域>.<句柄>`,7 别名/转发成员消灭)/battle_orchestrator 类变量 38→15(RoundCycle+BattleFacts 两件,叠加迭代 42 轴丙 BoardInstaller;encounter 归 BattleFacts、attune 改判状态两成员随件)/board_cell_unit 类变量 30→10+standee_body 类变量 19→10(各拆两独立文件,gdstyle inner-class 展平计数口径)/tune_sim 循环内 await 消除(process_frame 信号步进状态机;含**申报行为改动**一处:运行态收尾由每局置假还原为整批收尾单次置假——消除与 wd8/ui_tune_probe 断言面的静态矛盾,T0 实证定谳)。设计闭合凭据=architecture.md v1.25+五份设计文档(reports/ 下五件 设计-组合根注册面-2026-10-29.md/设计-战斗编排类变量归约-2026-10-29.md/设计-单格绘制状态件-2026-10-29.md/设计-站桩状态件-2026-10-29.md/设计-测速循环去await-2026-10-29.md)。四卡已成文(均零待裁点开工门 U0):
|
||||
|
||||
关联文档清单:
|
||||
- 组合根注册面批 reports/需求卡片-组合根注册面批-2026-10-29.md
|
||||
- 呈现层状态件批 reports/需求卡片-呈现层状态件批-2026-10-29.md(单格+站桩两设计并一卡)
|
||||
- 测速循环批 reports/需求卡片-测速循环批-2026-10-29.md
|
||||
- 战斗编排归约批 reports/需求卡片-战斗编排归约批-2026-10-29.md(接收方=在册条目「战斗域结构深拆批」宿主瘦身子项,不在本条目记账)
|
||||
|
||||
编队待迭代 42 合回(battle_orchestrator/board_view 触面碰撞约束),具体迭代归属归编排段;编入前置=各卡过 grilling 复核门。gdstyle inner-class 计数截断缺陷已在册(architecture v1.25)——基线登记值欠估,各批按真实口径施工;各批全部合回后一次人工 --refresh --force 收账。2026-10-29 编排(用户裁编法):卡 A 组合根注册面批+卡 B 战斗编排归约批+卡 D 测速循环批编入**迭代 44**(≈7.875 个工作日,中值合计);卡 C 呈现层状态件批编入**迭代 45**(与补件批同批,卡 C 先于其 board_hover 半边施工)。grilling 复核门已过(reports/复核-grilling-零豁免五卡-2026-10-29.md,五卡有条件成立、修正全落,提交 9855bf0a)。
|
||||
|
||||
**改动面**:游戏代码
|
||||
|
||||
**状态**:文档设计已闭合+已写卡+已编迭代 44+已编迭代 45
|
||||
|
||||
#### 数值标定窗口总挂账——原九条数值类条目合并(2026-10-28 登记,来源=会话提及)
|
||||
|
||||
**实况**:2026-10-28 用户令把九条数值类挂账合并为一条:削弱档位的最终数值/迭代 10 奖励重构联动欠账/调参批数值点评登记/三方向各自的解锁清单与定价/GP 经济换算失衡/天赋树实装批登记欠账余两件/商店独立刷新机制两参数/基线通关率越带加难杠杆扫描/成长系数节奏——原九条同步删除,内容全量迁入汇总文档,git 历史可考(本提交)。共同背景:M4 数值批卡已随 2026-10-16 删卡令退役;2026-10-18 用户裁=各条留待办清单、未设计未启动、不另行归属,未来数值标定窗口重开时重走设计段再写卡——本条沿用该裁定,重启条件=用户发令开窗口。合并动机=九条共享同一重启条件与同一执行形态(窗口内一次 MC 批量统一覆盖各条对比需求:全冒险期望+奖励期望+对拍锚重锚),分散登记徒增维护面。逐条挂账明细、裁定史与相关文档见汇总文档。
|
||||
@@ -93,7 +117,7 @@
|
||||
|
||||
**实况**:三条同病根的结构债,需先一次设计讨论定端口形态,再谈切卡;`RewardEconomy` 的最小缝拆样本已由迭代 40 卡② 落卡。
|
||||
- 效果发射端口(设计题本体):`game/core/damage_controller.gd:46/47/71` 与 `game/core/action_economy.gd:44/45/50` 仍直持 `EffectEngine`+`EffectContext`——前者用 attack_commit/armor_roll/clamp_check/kill/damage_taken 五枚事件并带计数器读写回写(:348/:354),后者用 dig_paid/dig_stop/charge_full 三枚事件。`RewardEconomy` 同款直连已由迭代 40 卡② p5 缝拆实装合回(单枚查询口 `luck_bias_query`——成员 −2+2、类变量净 15、判定归 `BattleFxHost.luck_bias_for`),最小样本在库可考;另两处事件多且带计数器回写,缝拆不成立,必须先设计「业务类只持一个回调、取回命中批」的端口形态。
|
||||
- battle_orchestrator 瘦身:迭代 40 卡① 拆出 `BattleFxHost`/`RewardGrant` 后宿主实测 38 类变量(阈值 15;豁免第三条已顺带落 architecture v1.22 S13 豁免登记——豁免不等于了结),`tools/gdstyle_baseline.txt` 在册 `game/core/battle_orchestrator.gd|quality/max-class-variables = 38` 与 `|quality/max-file-length = 1037` 两键(已随 2026-10-28 波 0 刷新按实测重锚)。
|
||||
- battle_orchestrator 瘦身:迭代 40 卡① 拆出 `BattleFxHost`/`RewardGrant` 后宿主实测 38 类变量(阈值 15;豁免第三条已顺带落 architecture v1.22 S13 豁免登记——豁免不等于了结),`tools/gdstyle_baseline.txt` 在册 `game/core/battle_orchestrator.gd|quality/max-class-variables = 38` 与 `|quality/max-file-length = 1037` 两键(已随 2026-10-28 波 0 刷新按实测重锚)。**2026-10-29 承接更新(本子项已写卡并编入迭代 44)**:设计闭合=architecture.md v1.25 轴丁(RoundCycle/BattleFacts 两新件,S13 豁免第三条注销——零豁免裁)+reports/设计-战斗编排类变量归约-2026-10-29.md;需求卡片:reports/需求卡片-战斗编排归约批-2026-10-29.md(v1.0 定稿零待裁点,grilling 复核过,编队前置=迭代 42 合回);本子项子目标=38→15,文件长键已由轴丙归绿。本条目其余两子项(效果发射端口/reward_economy 分件)仍待文档设计——下方状态行的「已写卡+已编迭代 44」两段专指本子项。
|
||||
- reward_economy 分件:`RewardEconomy` 现 15 类变量恰在阈值线上(加第 16 枚即出闸 09 新增红——迭代 40 卡② 施工实测撞见,正是本条登记起因),掷格面(install 期 roll/池行装配/权重合成)与受理账面(grant/身份查询/快照/retire)两职责同居一件。
|
||||
- 相关文档:design/engineering/architecture/architecture.md(系统分层图与功能层 B1/B4 行、「战斗编排域拆件定稿」节须随端口定稿改写)· reports/审计-gdstyle存量债清点与清偿方案-2026-10-26.md(216 键波次方案与残留债口径;在册「尾波」只覆盖迭代 39 三宿主,不含本条)· 结构小件定点修批卡已随迭代 40 合回退役(git 历史可考,合并提交 514457d1;缝拆样本与 2026-10-27 用户裁史见该卡 git 版本)
|
||||
|
||||
@@ -101,7 +125,7 @@
|
||||
|
||||
**改动面**:游戏代码
|
||||
|
||||
**状态**:待文档设计
|
||||
**状态**:待文档设计+已写卡+已编迭代 44
|
||||
|
||||
#### level_runner 商店委托层拆除——迭代 37 冻结契约期过渡件(2026-10-26 登记,来源=批次移交)
|
||||
|
||||
@@ -486,9 +510,3 @@
|
||||
**改动面**:文档+游戏代码+美术素材
|
||||
|
||||
**状态**:文档设计已闭合+待美术设计+已写卡
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in new issue
Block a user