主卡T3(拆件批wr4/wr5): 应用层收薄+构造注入+信号直连——adventure_runner六转发信号族与_forward_*方法删除(选路快照双职改核心侧受理_on_level_choices_presented直订level信号;stop信号中继删);level_runner构造注入一次给齐(_init收ctx十二键:hero/ledger瘦壳/adv_bucket/attunement/tree_rules活引用/shop_mode/treasure_unlocked/类型轴/凭证出箱/pool_wiring四参——后置setter群八件与set_hero/set_run_ledger退役,_bind_shop全仓仅构造一处,头注补关卡开始信号前零发射契约,八白盒属性内部改直指_shop);adv _start_current_level组包ctx(_inject_level_params退役改_emit_level_started只广播);呈现/测量信号直连(main_adventure_flow _connect_runner_once六信号level_started重取点is_connected守卫重连+三选一订stop();autoplay增订level_started同关守卫重连三信号;curio_interact_controller 14处adventure.stop()改址);测量面残留换代(bp_baseline_dump直连改level_started重连/ui_tune_probe与main_debug_flow keystone读hero());测试直连面换代(breakpoint_resume P5订stop()/adventure_feats信号序观测level_started回调内重连——bind句柄每回调新建不以Callable相等判重);sc3源码断言落hero_ledger_test(_bind_shop全仓仅构造一处/_forward_族零命中)〔拆件批 V5〕。验收:bp1对拍292dumps×27键逐位零漂移(改前/T1/T2/T3四时点一致)+十套件零红+csf集成绿+冒烟17项0失败〔拆件批 V4〕〔拆件批 V5〕

This commit is contained in:
DKChan committed 2026-10-27 03:51:35 +08:00
1 parent 4a9e4300ad
commit 4da7f3e2f2
13 files changed
+188276 -173

No files matched your search

+10 -5
View File
@@ -55,9 +55,9 @@ func _smoke_adventure_api() -> void:
# 入口停点观测(信号序 + 入口候选快照——容器写回规避 lambda 按值捕获)
var sig_seq: Array = []
var obs := {"entry_cands": []}
adr.level_started.connect(_api_mark_started.bind(sig_seq))
adr.choices_presented.connect(_api_mark_choices.bind(sig_seq, obs))
adr.node_entered.connect(_api_mark_node.bind(sig_seq))
# 直连面(转发信号退役):runner 信号在 level_started 回调内重连(构造期 runner 未建——
# 信号序观测=先广播后连接的同步链承载)
adr.level_started.connect(_api_mark_started.bind(sig_seq, obs, adr))
Kit.check("冒险启动受理(主种子注入恰一次——state=running;种子 42=首局固定种子生成图——精确路径断言需要确定图(卡② 代差))", adr.start_adventure(42))
Kit.check("进行中重复 start_adventure 拒绝(重开须待结算完毕)", not adr.start_adventure(43))
Kit.check("停点前移次序契约:level_started 先于入口候选呈现(反序选路口会被呈现层 runner 空防御丢弃)", sig_seq.size() == 2 and String(sig_seq[0]) == "level_started" and String(sig_seq[1]) == "choices_presented")
@@ -86,7 +86,12 @@ func _smoke_adventure_api() -> void:
# 观测桩(信号序采集——bind 容器写回,签名按各信号实参定制)
func _api_mark_started(_li: int, _dn: String, seq: Array) -> void:
func _api_mark_started(_li: int, _dn: String, seq: Array, obs: Dictionary, adr) -> void:
# 重取点重连(拆件批 T3 直连——回调时点 runner 已建;后续 choices_presented/node_entered 观测就位)
if not adr.runner().choices_presented.is_connected(_api_mark_choices):
adr.runner().choices_presented.connect(_api_mark_choices.bind(seq, obs))
if not adr.runner().node_entered.is_connected(_api_mark_node):
adr.runner().node_entered.connect(_api_mark_node.bind(seq))
seq.append("level_started")
@@ -410,7 +415,7 @@ func _smoke_adventure() -> void:
var a12 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(12))
a12.start_adventure(12)
var cap := {"payload": {}}
a12.curio_choice_presented.connect(func(p): cap["payload"] = p)
a12.stop().curio_choice_presented.connect(func(p): cap["payload"] = p) # 停点件信号面(拆件批 T3 直连)
var max_full: int = int(_db.hero.max_hp) + int(a12.hero().base_override_flat().get("max_hp", 0))
a12.hero().hero_hp = max_full
a12._on_level_finished({"result": "victory", "hp": max_full, "node_index": 1, "node_id": 1, "node_type": "shop"})
@@ -106,7 +106,7 @@ func _init() -> void:
var got_cands := {"cands": [] as Array}
var adr_f = AdventureRunnerScript.new(db, load("res://core/rng_service.gd").new())
adr_f.set_save_manager(sm_f) # 兑付后停点快照落盘承载(与真机组合根同构)
adr_f.curio_choice_presented.connect(func(p): got_cands["cands"] = (p.get("candidates", []) as Array).duplicate())
adr_f.stop().curio_choice_presented.connect(func(p): got_cands["cands"] = (p.get("candidates", []) as Array).duplicate()) # 停点件信号面(拆件批 T3 直连)
Kit.check_quiet(adr_f.resume_adventure(bp_f, params_e), "P5 续玩受理(选择态分支)")
Kit.check_quiet(adr_f.runner() == null, "P5 续玩不重跑关卡(三选一停点直回,_start_current_level 未走)")
Kit.check_quiet(got_cands["cands"] == cands_e, "P5 续玩候选不重抽(逐位一致)")
@@ -123,7 +123,7 @@ func _init() -> void:
var adr_g = AdventureRunnerScript.new(db, load("res://core/rng_service.gd").new())
adr_g.set_save_manager(sm_f) # 已兑付态续玩的后续快照同承载
var got_result := {"r": {}}
adr_g.curio_resolved.connect(func(r): got_result["r"] = r.duplicate())
adr_g.stop().curio_resolved.connect(func(r): got_result["r"] = r.duplicate()) # 停点件信号面(拆件批 T3 直连)
Kit.check_quiet(adr_g.resume_adventure(bp_g, params_e), "P5 已兑付态续玩受理")
Kit.check_quiet(String(got_result["r"].get("picked", "")) == picked_e, "P5 已兑付不重付(resolved 重发同件)")
Kit.check_quiet(adr_g.continue_to_next_level(), "P5 已兑付续玩后推进受理(下一关开始)")
+19 -1
View File
@@ -121,4 +121,22 @@ func _init() -> void:
Kit.check_quiet(h5.bonus_total("atk") == 0,
"hr2 汇总与日记推导不符→拒载(汇总不回填——日记为正主)")
quit(Kit.finish("hero_ledger_test", "PASS — 主角账公式/三通道日记/断点片段往返与旧档回退 全绿"))
# ---- sc3 源码断言(拆件批 T3——构造注入收口与转发族退役的静态面)----
var adv_src := FileAccess.get_file_as_string("res://core/adventure_runner.gd")
var lvl_src := FileAccess.get_file_as_string("res://core/level_runner.gd")
var bind_shop_adv: int = adv_src.count("func _bind_shop")
var bind_shop_lvl: int = lvl_src.count("func _bind_shop")
var bind_calls := 0 # 调用行计数(排除 func 定义行——行首剥缩进后以 _bind_shop() 起始)
for line in (adv_src + lvl_src).split("
"):
var t := line.strip_edges()
if t.begins_with("_bind_shop()"):
bind_calls += 1
Kit.check_quiet(bind_shop_adv == 0 and bind_shop_lvl == 1,
"sc3 _bind_shop 定义全仓仅 level_runner 构造一处(商店重绑机制退役)〔拆件批 V5〕")
Kit.check_quiet(bind_calls == 1,
"sc3 _bind_shop 调用全仓仅构造一处(bind_calls=%d)〔拆件批 V5〕" % bind_calls)
Kit.check_quiet(not adv_src.contains("_forward_") and not adv_src.contains("signal node_entered"),
"sc3 六转发信号族与 _forward_ 转发方法全仓零命中(信号直连收口)〔拆件批 V5〕")
quit(Kit.finish("hero_ledger_test", "PASS — 主角账公式/三通道日记/断点片段往返与旧档回退/源码断言 全绿"))