21 KiB
需求卡片:孤儿函数清退批
来源:待办清单「EffectEngine 死函数与全仓孤儿函数清退」(2026-11-04 登记,来源=会话提及,优先级=P0;需求性工程条目,证据指认在条目实况)。唯一事实源:该条目实况证据链+本卡第 3 节 2026-11-04 全仓排查考证(排查总体/口径/判死清单逐件实查)。 裁决沿革:删除方向 2026-11-04 用户裁(删
has_effect_on并全仓排查生产码零调用死函数一并清退);排查口径按登记(生产码为排查总体;测试直连与受控例外面不判死)。 验收档:中 版本:v1.0(2026-11-04)
1. 目标与完成定义
产品码三目录孤儿函数清零:
- 判死清单六件(§3.2)零调用方死函数删除(含各自专属文档注释行);
- 删除后级联零新增孤儿(关联在役成员逐件留存复核);
- 游戏行为零变化(六件全为无调用方死件,删除无运行期可观测面)。
完成定义:六件定义行消失且全仓(.gd+.tscn)零残留;级联留存复核通过(§3.2 级联核列);既有套件全绿;--code 域全套闸绿。
2. 设计事实源
需求性工程条目(死码清退,无设计线):设计事实源=证据指认——待办清单条目实况(game/core/effect_engine.gd:204 has_effect_on 全仓零调用方,登记证据;2026-11-04 用户裁删并全仓排查)+本卡第 3 节 2026-11-04 全仓排查复核(file:line 逐件实查)。
3. 现状事实(2026-11-04 全仓排查考证)
3.1 排查口径与方法(可复现)
- 排查总体=
game/core+game/data+game/presentation全部func定义(code-conventions §4.13 产品码三目录口径;game/根目录无散落 .gd——find 已证)。 - 语料=
game/下全部 .gd 与 .tscn 的非注释行(.tscn 覆盖信号接线method=形态)。 - 判死=全仓零调用方——测试/sim/probe 直连不判死(登记口径);引擎虚函数(
_init/_ready/_process等)除外。 - 方法:逐函数名全仓标识符检索(词边界)→ 剥注释 → 定义行外零出现=死函数候选 → 逐件人工复核调用形态(排除字符串标签/跨类同名噪声;同名多定义清单已核,六件名均无跨类同名定义)。
3.2 判死清单(六件)
| # | 件 | 定义(含注释) | 职责 | 零调用证据 | 级联核(保留面) |
|---|---|---|---|---|---|
| 1 | has_effect_on |
effect_engine.gd:203-212 | 订阅查询面(发射点缺省行为仲裁——round_end 走 RAP 转存后成死件) | 登记证据+本次全仓 grep 仅定义命中 | _triggers/dispatch(:218)在役不受影响 |
| 2 | _bp_read_int |
breakpoint_store.gd:211-219 | 数值类读侧 helper(clamp/params_fallback 策略分支) | 全仓零调用;生产读侧=bp_read(:197,消费 keep_on_null/plain) |
_bp_strategy(:207)由 bp_read 共用——保留;BREAKPOINT_FIELDS 的 clamp/params_fallback 策略标签保留(文档标签;其机械消费面缺失在案观察,见 §3.3 注④) |
| 3 | _find_token |
adventure_runner.gd:250-252 | 死包装——转发 _curio.find_token,而 curio_stop 无此方法(若被调用即运行期错误);真件=curio_deck.find_token(curio_deck.gd:51,curio_stop.gd:107/:229 在役消费) |
全仓零调用 | curio_deck.find_token 保留(活) |
| 4 | has_open |
modal_stack.gd:56-62 | 开态查询(组合根输入锁判据位) | 全仓零调用——组合根实际消费 has_open_excluding_tags(空标签集=全计,同形;:65-67 注释自证) |
独立谓词,零级联 |
| 5 | set_feedback_state |
camp_scene_view.gd:88-92 | 持久基态外部设置口 | 全仓零调用——视图内 _handle_motion 族自持(_apply_state :113/:116/:118/:127/:133 在役) |
_apply_state/_base_state/_base_states 保留 |
| 6 | stop_resolved |
curio_stop.gd:303-305 | 放行谓词(宿主关序受理) | 全仓零调用 | _resolved 多读写在役(:207/:215/:216/:343/:360/:394/:401/:413);_pending 由 curio_stop_pending(:300)消费——均保留 |
3.3 B 段清单——生产码零调用、仅 sim/probe/tests 出现(登记口径保留,不判死)
排查另得 69 件(附表全列)+ _init/_ready 引擎虚函数面(排除)。重点注记:
- 注①:
config_db.gd:170_validate_skill_pool_links——被跨表校验件取代的旧实现:生产真身=config_db_cross_validator.gd:197-213(同判定类别 dangling_skill/pool_composition,检查面更全);旧件生产零调用、测试直连 5 处(round_flow_skill_pool_test.gd:869/871/876/893/905)——测试锚在被取代实现。去向=新立待办条目(写卡段同批登记),不在本卡收件。 - 注②:
gp_wallet.gd:10gain_gp——生产零调用、测试造数面(hero_ledger_test.gd:105)——保留。 - 注③:
main.gd:106_start_adventure_from_menu——在册中间态(代码注释自证:探针直调位点 mn10 逐个登记,卡④到位后由大门两分支换代)——非孤儿发现,保留。 - 注④:
breakpoint_store.gd的 BREAKPOINT_FIELDS 策略标签clamp/params_fallback(:19/:20/:39/:40/:41)机械消费面随_bp_read_int死亡——标签保留为文档语义,是否补消费面或清标签归后续裁决(本卡不动)。 - 其余 B 段件=探针取证面(
*_probe/press_*_for_probe)、调试面(debug_overlay 族)、测量面(playtest_logger/sim 消费)与测试造数面——按登记口径全部保留。
B 段附表(69 件全列):
| 定义处 | 函数名 | 保留面调用计数 |
|---|---|---|
| presentation/main.gd:106 | _start_adventure_from_menu | probe:11, test:6 |
| core/config_db.gd:170 | _validate_skill_pool_links | test:5 |
| core/slot_store.gd:48 | active_slot | probe:5, test:11 |
| presentation/views/hero_info_panel_view.gd:156 | armor_text | probe:2 |
| core/slot_store.gd:24 | attach_path | probe:3, test:9 |
| core/slot_store.gd:34 | attach_slot_template | probe:4, test:15 |
| presentation/views/hero_info_panel_view.gd:152 | attack_text | probe:3 |
| core/battle_orchestrator.gd:152 | attune_has | test:8 |
| core/level_runner.gd:482 | awaiting_choice | probe:5, sim:1, test:19 |
| presentation/views/level_map_screen.gd:589 | canvas_probe | probe:3, test:1 |
| presentation/views/board_view.gd:442 | cell_center_local | probe:1 |
| presentation/views/board_view.gd:845 | cell_rect_probe | probe:3 |
| presentation/views/board_view.gd:817 | cells_probe | probe:25 |
| presentation/views/board_view.gd:419 | click_cell | probe:7 |
| presentation/views/ap_bar_view.gd:197 | confirm_visible | probe:1 |
| presentation/views/standee_body.gd:355 | content_rect | probe:1 |
| data/schemas/adventure_table.gd:165 | deck_total | test:2 |
| core/config_db.gd:86 | diagnostics | sim:1, test:17 |
| presentation/views/board_view.gd:822 | diggable_probe | probe:8 |
| presentation/views/level_map_screen.gd:595 | display_probe | probe:2, test:1 |
| presentation/views/debug_overlay.gd:69 | effect_text | probe:2 |
| presentation/views/battle_stage_view.gd:262 | enemy_body_at | probe:2 |
| presentation/views/board_view.gd:832 | fog_params_probe | probe:5 |
| presentation/views/battle_end_overlay.gd:382 | fx_probe | probe:10, test:1 |
| presentation/views/standee_body.gd:217 | fx_probe | probe:10, test:1 |
| core/gp_wallet.gd:10 | gain_gp | test:1 |
| presentation/views/camp_scene_view.gd:83 | get_hotspot_rect | probe:1 |
| core/slot_store.gd:53 | has_write_target | test:9 |
| presentation/views/standee_body.gd:304 | hero_state_probe | probe:4 |
| presentation/views/board_view.gd:827 | hover_probe | probe:2 |
| presentation/views/standee_body.gd:57 | intent_probe | probe:4 |
| core/reward_economy.gd:74 | is_mapped | sim:1 |
| presentation/views/level_map_screen.gd:584 | layout_probe | probe:7, test:5 |
| presentation/playtest_logger.gd:45 | log_path | sim:11, test:2 |
| presentation/playtest_logger.gd:118 | log_run | sim:2 |
| presentation/views/standee_body.gd:64 | name_line_probe | probe:1, test:3 |
| core/level_runner.gd:400 | next_candidates | sim:1, test:2 |
| presentation/views/debug_overlay.gd:121 | output_text | probe:1 |
| presentation/views/battle_log_view.gd:102 | parsed_text | probe:2, test:6 |
| presentation/views/standee_body.gd:283 | portrait_probe | probe:2, test:3 |
| presentation/views/debug_overlay.gd:127 | press_apply_for_probe | probe:2 |
| presentation/views/level_map_screen.gd:402 | press_candidate | probe:8, test:1 |
| presentation/views/curio_pick_overlay.gd:157 | press_card | probe:3, test:2 |
| presentation/views/curio_pick_overlay.gd:163 | press_confirm | probe:3, test:1 |
| presentation/views/ap_bar_view.gd:201 | press_confirm_for_probe | probe:1 |
| presentation/views/curio_pick_overlay.gd:167 | press_continue | probe:7, test:1 |
| presentation/views/node_overlay.gd:33 | press_continue | probe:7, test:1 |
| presentation/views/curio_pick_overlay.gd:172 | press_refresh | test:2 |
| presentation/views/ap_bar_view.gd:193 | press_refresh_for_probe | probe:1 |
| presentation/views/debug_overlay.gd:131 | press_reset_for_probe | probe:1 |
| presentation/views/debug_overlay.gd:135 | press_simulate_for_probe | probe:1 |
| core/minesweeper_rules.gd:397 | preview_reveal | sim:1, test:6 |
| core/treasure_items.gd:236 | probe | probe:24, test:51 |
| presentation/views/settlement_fx_view.gd:73 | probe_banners | probe:3 |
| presentation/views/settlement_fx_view.gd:78 | probe_settlement_marks | probe:1 |
| presentation/views/ap_bar_view.gd:206 | refresh_remaining_text | probe:3 |
| core/refresh_bank.gd:38 | refresh_y | sim:2, test:10 |
| core/config_db.gd:180 | reload | probe:2, test:4 |
| core/config_db.gd:81 | reset_diagnostics | test:3 |
| presentation/views/settings_overlay.gd:26 | retarget | probe:1 |
| presentation/views/debug_overlay.gd:101 | run_data_probe | probe:1 |
| presentation/views/board_view.gd:163 | set_fog_enabled | probe:2 |
| presentation/views/debug_overlay.gd:73 | set_sim_count | probe:1 |
| presentation/views/debug_overlay.gd:58 | set_sliders | probe:4 |
| presentation/views/board_view.gd:345 | set_type_glow_enabled | probe:4, test:5 |
| core/level_runner.gd:144 | start_level | probe:2, sim:2, test:11 |
| presentation/debug_session.gd:31 | start_single | probe:1 |
| presentation/views/board_view.gd:837 | type_glow_probe | probe:13, test:11 |
| presentation/views/battle_end_overlay.gd:204 | verdict_text | probe:2 |
4. 设计契约(🔴 违反即 L3 停机呈报)
- 🔴 游戏行为零变化——六件全为零调用方死件,删除零运行期可观测面;零 RNG/信号/存档/表值触面。
- 🔴 级联零新增——删除后全仓不得出现新孤儿函数(§3.2 级联核列逐件留存复核,T2 判据)。
- 🔴 范围纪律——只删 §3.2 六件;B 段一律不收(注①去向=新立待办);禁顺手清 tests/sim/probe 面(非生产码)。
- 🔴 禁保留无效成员——删函数禁留空壳/别名/注释存根(code-conventions §1.1 拆分判据⑤)。
- 🔴 断言零削弱——六件无测试直连(grep 已证),测试文件零触碰、零断言改判。
- 🔴 实现批禁写
design/整个目录与根规则文件(architecture.md 六件名 grep 零命中,无反哺点——已核)。 - 🔴 MC/模拟零跑——无数值改动。 8. 🔴 车道铁律——实现走独立 worktree。
5. 范围边界
做:§3.2 六件删除(含各自专属文档注释行;六件行段见 §7 文件结构图)。
不做:
- B 段全部 69 件(§3.3;注①去向=新立待办条目,注④归后续裁决);
- 六件级联核保留面(§3.2 末列);
- tests/sim/probe 面的孤儿排查(非生产码,不在登记范围)。
明示不收件的去向:待办清单新立条目「config_db._validate_skill_pool_links 旧校验件清退与测试改锚」(写卡段同批登记)。
6. 关联文档同步面
| 文档 | 关联点(本批实现会改变它的哪条陈述) | 同步义务 |
|---|---|---|
design/engineering/architecture/architecture.md |
六件名 grep 零命中(has_effect_on/bp_read_int/find_token/has_open/set_feedback_state/stop_resolved 全零——已核) | 无同步义务(零反哺点) |
game/tests/README.md |
六件名零命中能力清单(已核);六件所属套件能力行不受影响 | 实现批禁写——批末收尾核对名实一致(零回表预期) |
| 术语表/GDD 各系统文档 | 零关联(纯代码面清退) | 无同步义务 |
| 待办清单 | 本条目状态推进+新立注①条目 | 状态推进归流水线各段,实现批不碰 |
7. 任务卡
卡前文件结构图(零新增文件;六件全为非行为改动):
| 文件 | 改动 | 行为改动 |
|---|---|---|
game/core/effect_engine.gd |
删 :203-212(文档注释+函数) | 否(对照表行 1) |
game/core/breakpoint_store.gd |
删 :211-219(注释+函数) | 否(行 2) |
game/core/adventure_runner.gd |
删 :250-252(注释+函数) | 否(行 3) |
game/presentation/modal_stack.gd |
删 :56-62(注释+函数) | 否(行 4) |
game/presentation/views/camp_scene_view.gd |
删 :88-92(函数;无专属注释块) | 否(行 5) |
game/core/curio_stop.gd |
删 :303-305(注释+函数) | 否(行 6) |
T0 基点读数(≈0.2 工作日)
- 六件定义处行号与所在文件基线键读数固化(
adventure_runner.gdmax-class-variables=23 在册,其余五文件 grep 基线键记录)——落实现报告(删除后只降不升核对面) - 六件零调用方证据复核:逐件全仓 grep(.gd+.tscn,词边界)仅定义命中——与 §3.2 一致;不一致即停卡(L3-①)
T1 六件删除(≈0.3 工作日)
effect_engine.gd:删 :203-212(## 订阅查询面…注释+has_effect_on函数体)breakpoint_store.gd:删 :211-219(# 数值类读侧…注释+_bp_read_int函数体)adventure_runner.gd:删 :250-252(# 候选令牌匹配…注释+_find_token转发行)modal_stack.gd:删 :56-62(# 开态查询…注释+has_open函数体)camp_scene_view.gd:删 :88-92(set_feedback_state函数体)curio_stop.gd:删 :303-305(# 放行谓词…注释+stop_resolved函数体)- 各删除点相邻空行规范化(两空行分隔惯例保持)
T2 级联与零残留复查(≈0.15 工作日)
- 六件名全仓 grep(.gd+.tscn,词边界)零残留
- 级联留存复核(grep 计数落实现报告):
_bp_strategy/bp_read、curio_deck.find_token、has_open_excluding_tags、_apply_state族、_resolved/_pending、_triggers/dispatch各 ≥1 在役调用方 - 新增孤儿扫描:按 §3.1 口径复查六文件——删除不产生新零调用函数
T3 验证闸(≈0.15 工作日)
- 孤立验证:
…console.exe --script res://tests/run_all.gd单测域全绿(重点 effect_port/breakpoint/curio/modal/camp/adventure 关联套件) - 里程碑步出口:
tools/run_all_gates.sh --code全绿
T4 产出物落位卡(≈0.1 工作日)
reports/iter<N>-实现报告-<日期>.md:各卡状态+实现决定记录+级联留存复核计数+实机目检总清单(登记「无实机目检项」——死件删除零玩家可观测提交面)reports/iter<N>-反哺点-<日期>.md:零条(§6 已核;文件仍须落,写明「零反哺点」)
估时:合计中值 ≈0.9 个工作日(区间 0.75–1.25)。
8. 验证闸(改动—验收对照表)
| # | 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点+尾缀) | 层级 | 真实入口 | 判据绑定面 | 能力行 |
|---|---|---|---|---|---|---|---|
| 1 | has_effect_on 退役(登记原件) | effect_engine.gd:203-212 删 |
静态判据:T2 零残留 grep+既有套件全绿(effect_port_test 等当轮跑批执行) | 静态+单元 | tools/run_all_gates.sh --code(09 静态扫描+00/01 保险) |
定义行消失+全仓零残留+回归绿三面(死函数无运行期提交面——静态判据+评审注记申报观测面局限) | 既有:效果发射端口单点 |
| 2 | _bp_read_int 退役 | breakpoint_store.gd:211-219 删 |
同行 1(断点关联套件为回归锚) | 静态+单元 | 同行 1 | 同行 1 | 既有:断点片段往返与续玩幂等 |
| 3 | _find_token 退役(死包装) | adventure_runner.gd:250-252 删 |
同行 1(adventure 关联套件为回归锚) | 静态+单元 | 同行 1 | 同行 1 | 既有:冒险生命周期:开局受理/三关序列/败北线 |
| 4 | has_open 退役 | modal_stack.gd:56-62 删 |
同行 1(modal 关联套件为回归锚) | 静态+单元 | 同行 1 | 同行 1 | 既有:模态覆盖层编排与输入锁 |
| 5 | set_feedback_state 退役 | camp_scene_view.gd:88-92 删 |
同行 1(camp 关联套件/探针为回归锚) | 静态+单元 | 同行 1 | 同行 1 | 既有:营地场景图十层铺底与门洞留空呈现 |
| 6 | stop_resolved 退役 | curio_stop.gd:303-305 删 |
同行 1(curio 关联套件为回归锚) | 静态+单元 | 同行 1 | 同行 1 | 既有:奖励三选一候选/刷新付费/呈现 |
| 7 | 级联零新增(完成定义判据) | 六件删除的伴生核(无新增代码改动) | T2 级联留存复核:§3.2 末列六组保留面 grep 计数各 ≥1 在役调用方+新增孤儿扫描(按 §3.1 口径复查六文件零新孤儿)——计数落实现报告 | 静态 | 同行 1 | 保留面调用计数与新孤儿扫描零命中=本批级联判据特有提交面 | 既有:效果发射端口单点 |
- 非行为改动行:六行全部为非行为改动(判断依据:被删函数全仓零调用方〔§3.2 证据〕=无运行期提交面;既有套件全绿兜底)。
- 测试方式两分法:本批全部归静态判据+套件回归锚;无用户目检项(零玩家可观测提交面)。
- 测试削弱申报:无——测试文件零触碰(六件无测试直连,grep 已证)。
- 独立验收审计:
reports/iter<N>-验收审计-<日期>.md,未参与实现的会话或子代理执行,未过不得合并(test-conventions §8.7;验收档中=对照表全量核对+判据绑定面抽查+复跑以远端 CI 现查读数代证)。 - 回归措辞:里程碑步(T3)出口跑一次
--code域全套闸;卡内修复只做出红最小单元的最窄确认。
9. 异常分级
- L1 自救:空行规范化笔误、grep 白名单笔误。
- L2 记录继续:级联留存复核的计数呈现形态(记录进实现报告)。
- L3 停机呈报:①T0 复核发现任一件实有调用方(字符串派发/动态接线漏判=上游考证缺陷,停卡退回写卡段);②级联复查发现新孤儿(误判级联);③机检键与本卡契约互斥(禁改闸件豁免);④全套闸红不可最小单元收敛。
10. 代拍板白名单
- 删除点相邻空行规范化。
- T2 复核计数落实现报告的表格形态。
11. 待裁点
零待裁点——删除方向 2026-11-04 用户裁;排查口径按登记(生产码总体+测试直连不判死);B 段保留与注①去向新立待办=登记口径的执行。开工门=grilling 复核+用户裁决+迭代编排(编入迭代后估时总量 <5 工作日=冻结待凑批)。
12. 落位与可复用性预检
- 复用面:零新增件——纯删除。
- 唯一面:删除不产生第二落点;三组同名体已核辨——
curio_deck.find_token(在役真件)与被删_find_token(死包装)是两个标识符域;has_open与has_open_excluding_tags(在役)同理;stop_resolved与信号curio_resolved(在役)同理。 - 分层与交互面:零跨层变化——六件均无调用方,删除不改变任何调用路径;Core 零 UI 依赖不因删除新增绕行;零表值触面。
13. 禁为机检文本保留无效成员
🔴 适用(删除侧反向)——禁为保机检键/计数留空壳、别名、注释存根;删除与机检键互斥时实现段一律停卡呈报,不得自造第三条路。
14. 实现规范预算
零新增文件——三查不适用。存量触面六文件:函数删除不改类变量数(adventure_runner.gd max-class-variables=23 在册,读数不变);gdstyle 函数级键(若有)只降不升;S13 公开方法数只降不升(六件中 has_effect_on/has_open/set_feedback_state/stop_resolved 为公开方法——四文件 S13 计数各 −1,T0 读数承载)。全部触面 S13 键较登记值只降不升。
15. 拆分边界纪律
本卡为删除类(非拆分/收敛类),无拆出单元。红线:禁为凑指标或摊薄审查把六件拆多批留尾——六件一次清完(T1 六个复选框是施工粒度,非范围拆分);禁把 B 段任何件搭车收进本批(§4 契约 3)。