diff --git a/game/core/adventure_runner.gd b/game/core/adventure_runner.gd index 9bc55a08..379f423a 100644 --- a/game/core/adventure_runner.gd +++ b/game/core/adventure_runner.gd @@ -834,7 +834,7 @@ func abandon() -> bool: func _start_current_level() -> bool: _runner = LevelRunner.new(db, rng) - # 树限次计数按关清零现由 LevelRunner.level_counters 随每关 new 天然承载(旧硬编码清除名单 _reset_tree_limited_counters 已删) + # 树限次计数按关清零现由 LevelRunner.level_counters 随每关 new 天然承载(旧硬编码清除名单函数已删) # core↔core 接线只许方法 Callable(S6——lambda 捕获 self 会延长 RefCounted 生命周期乃至成环) _runner.node_entered.connect(_forward_node_entered) _runner.choices_presented.connect(_forward_choices_presented) diff --git a/game/core/battle_orchestrator.gd b/game/core/battle_orchestrator.gd index 38c9b0f0..6ee113f6 100644 --- a/game/core/battle_orchestrator.gd +++ b/game/core/battle_orchestrator.gd @@ -395,7 +395,7 @@ func begin_battle(enc: Dictionary) -> bool: var tree_rules: Array[Variant] = enc.get("tree_rules", []) as Array # 效果引擎订阅重建(每战从持有集/装备集重建,中途获得下一战生效; # 树规则合成订阅同面装载。装载序=feats 表序→treasure 表序→树规则,写死保种子复放。 - # 计数器四桶经 counters_ctx 引用宿主容器,无回灌时点(旧 counters_seed 删除)) + # 计数器四桶经 counters_ctx 引用宿主容器,无回灌时点(旧战首回灌时点删除)) _fx.rebuild(feat_ids, attunement, tree_rules) # 秘宝常时参数注入(装配集 kind 分发:远程镐挖距放宽/信标网络封印可达豁免; # 缺省 0/false=零装配零扰动。注入在首板 install 之后〔板在早段〕——板生成不读两参数, @@ -1124,7 +1124,7 @@ func _battle_over(result: String) -> void: for axis in _fx_bonus_delta.keys(): _ledger.bonus_add_axis(axis, int(_fx_bonus_delta[axis])) _fx_bonus_delta = {"atk": 0, "max_hp": 0, "armor_class": 0, "ap": 0} - # 搬运链删除:adventure 桶经 ctx 引用直写 RunLedger,无战末导出时点(旧 counters_export/merge_export) + # 搬运链删除:adventure 桶经 ctx 引用直写 RunLedger,无战末导出时点(旧导出/汇入搬运链删除) # 映射随战斗结束退役(地图战斗资源 义务④——下一场战斗 = 新板新 scope 批,roll_board 相位守卫的前提) var hero_hp_left := int(_enemy_system.hero_unit().get("hp", 0)) # despawn 前捕获(信号载荷供呈现层"HP 带入下一层") var gp_dropped := _roll_gp_drop() # 战斗掉落(escrow 随此值上抛即弃) diff --git a/game/smoke/smoke_all.gd b/game/smoke/smoke_all.gd index 011a90e8..dd8c2b10 100644 --- a/game/smoke/smoke_all.gd +++ b/game/smoke/smoke_all.gd @@ -6066,7 +6066,7 @@ func _smoke_tree_rules() -> void: # 危险直觉·锋:限次闸(引擎直构——mine_hit 挂点现成;限次计数住 level 桶,跨战持久=共享同一字典引用) var fz = load("res://core/effect_engine.gd").new(null) fz.rebuild([], [], ["sense_sharp"]) - var lvl_shared := {} # 同一关的 level 桶(两编排器共享引用 = 跨战持久,替代旧 counters_export/seed 副本搬运) + var lvl_shared := {} # 同一关的 level 桶(两编排器共享引用 = 跨战持久,替代旧副本搬运) var ctx_fz := EffectContext.new() ctx_fz.level_bucket = lvl_shared var got_mult := false @@ -6084,7 +6084,7 @@ func _smoke_tree_rules() -> void: var ctx_fz2 := EffectContext.new() ctx_fz2.level_bucket = lvl_shared # 挂同一 level 桶引用(新形态跨战持久:无 export/seed,同字典即持久) check((fz2.dispatch(ctx_fz2, "mine_hit", {}, Callable()) as Array).is_empty(), - "锋:限次跨战持久(level 桶共享引用——替代旧 adventure 域 counters_export/seed 副本搬运)") + "锋:限次跨战持久(level 桶共享引用——替代旧副本搬运链)") # 守侧五场景(契约 12):编排 rig——begin_battle 携 sense_guard,授予段 _grant_seg._judge_seal 直注 var orch = load("res://core/battle_orchestrator.gd").new(_db, _fresh_rng(777001)) check(orch.begin_battle({"level_index": 1, "node_depth": 0, "hero_hp": 40, "hero_atk": 8, "hero_max_hp": 40, diff --git a/game/tests/static_scan.sh b/game/tests/static_scan.sh index 245ffa6e..9e218b31 100644 --- a/game/tests/static_scan.sh +++ b/game/tests/static_scan.sh @@ -210,4 +210,27 @@ else fi fi +# ── S12 — 效果引擎无状态化旧件零残留(卡② V10/F1;禁 counters_export/counters_seed/_reset_tree_limited_counters 等旧符号与带引号旧 id 字面回归)── +# 扫描面:game/ 全域 .gd 与 game/data/tables/*.tres(改名与旧符号同时存在于数据行/测试/smoke,非仅 core——不扩面即空转) +# 带引号旧 id 匹配("twin_digs" 不误伤 "adv_twin_digs"——引号锚定;round_instinct_atk 不匹 "instinct_atk") +# 自检:扫描面文件数为零即判红(防静默空转) +if [ -d game/core ]; then +S12_SYM='counters_export|counters_seed|counters_merge_export|counters_seed_snapshot|_reset_tree_limited_counters|"tree_sense_sharp_used"|"tree_sense_guard_used"|"twin_digs"|"instinct_atk"' +S12_FACE=$(find game/ -type f \( -name '*.gd' -o -name '*.tres' \) 2>/dev/null) +S12_FC=$(echo "$S12_FACE" | grep -c .) +if [ "$S12_FC" -eq 0 ]; then + echo "[static_scan] S12 FAIL: 扫描面为空——路径写错导致的静默空转" + fail=1 +else + S12_HITS=$(echo "$S12_FACE" | tr '\n' '\0' | xargs -0 grep -lEn "$S12_SYM" 2>/dev/null | wc -l) + if [ "$S12_HITS" -gt 0 ]; then + echo "[static_scan] S12 FAIL: 无状态化旧件残留命中 $S12_HITS 文件" + echo "$S12_FACE" | tr '\n' '\0' | xargs -0 grep -En "$S12_SYM" 2>/dev/null + fail=1 + else + echo "[static_scan] S12 ok(扫描面 $S12_FC 个 .gd/.tres,旧件零残留)" + fi +fi +fi + exit $fail diff --git a/game/tests/unit/core/effect_words_t1_test.gd b/game/tests/unit/core/effect_words_t1_test.gd index bd2af281..d0c44dc2 100644 --- a/game/tests/unit/core/effect_words_t1_test.gd +++ b/game/tests/unit/core/effect_words_t1_test.gd @@ -87,12 +87,12 @@ func _init() -> void: if String(h.get("kind", "")) == "counter_add": EffectEngine.counter_add(ctx3, String(h.get("counter_id", "")), int(h.get("value", 0))) Kit.check_quiet(EffectEngine.counter(ctx3, "adv_persist") == 2 and int(adv_bucket.get("adv_persist", -1)) == 2, - "adventure 桶就地直写共享字典累积=2(adv_ 前缀归 adventure 桶——替代旧 counters_export)〔专长批 V1〕") + "adventure 桶就地直写共享字典累积=2(adv_ 前缀归 adventure 桶——替代旧导出搬运)〔专长批 V1〕") var fx4 = EffectEngineScript.new(null) fx4._push_trigger("test", "adv_row2", {"on": "mine_hit", "do": {"kind": "counter_add", "counter_id": "adv_persist", "value": 1}}, {}) var ctx4 := EffectContext.new() - ctx4.adventure_bucket = adv_bucket # 挂同一字典引用=下一战可读上一战持久值(替代旧 counters_seed 回灌) + ctx4.adventure_bucket = adv_bucket # 挂同一字典引用=下一战可读上一战持久值(替代旧回灌) Kit.check_quiet(EffectEngine.counter(ctx4, "adv_persist") == 2, "adventure 桶共享引用跨引擎可读(无 export/seed,同字典即跨战持久)〔专长批 V1〕") diff --git a/game/tests/unit/core/feat_vouchers_test.gd b/game/tests/unit/core/feat_vouchers_test.gd index a48c6090..e449750e 100644 --- a/game/tests/unit/core/feat_vouchers_test.gd +++ b/game/tests/unit/core/feat_vouchers_test.gd @@ -111,7 +111,7 @@ func _init() -> void: # V16——断点扩容往返:新账本随断点快照/续玩回填(breakpoint_resume_test P5 同构) var sm = load("res://core/save_manager.gd").new("user://_feat_vouchers_bp.json") sm.load_from_disk() - a.run_ledger.adventure_counters = {"pain_layers": 3, "twin_digs": 5} # 四账住 RunLedger + a.run_ledger.adventure_counters = {"pain_layers": 3, "adv_twin_digs": 5} # 四账住 RunLedger a._refresh_stock = 2 a.set_save_manager(sm) a._on_level_finished({"result": "victory", "hp": 10, "node_index": 1, "node_id": 1, "node_type": "shop"})