卡②(结构小件批p1-p7+V15): 七点定点修落地+运行期违约通道负面套件+wr10 偏运缝拆验收——①p1 状态角标判据去重(main_overlay_flow._sync_status_entry 一组重复赋值语句删除,battle_live 局部量随之退役=wr1 载体);②p2 确认窗开合归模态栈单口(main 两处 _on_confirm_* 改 _close_modal;存档删除入口改 root._open_modal(root.confirm_dialog) 后再 open,遮挡记账/挂起兜底/开侧同步同口);③p3 棋盘动作与 stop 两入口显式 settlement 空防护(锁谓词异常时不崩于空引用);④p4 会话更替即清队:_begin_session 首行 _row_pacer.flush()(待播行不住局态=机制保证非时序约定);⑤p5 缝拆:RewardEconomy 删跨域直持(_fx/_ctx/set_fx)改注入 luck_bias_query: Callable,reward_roll 发射与 bias_rewards 求和收回 BattleFxHost.luck_bias_for(cell_count)(三参形 dispatch,不带 facts——禁复用 fx_emit 的第四实参会打开 when 事实条件面),组装点 set_fx 一行换赋值一行 1 换 1;类变量 15−2+2 净 15,gdstyle 无第 16 枚;⑥p6/p7 RngService 未知用途标签与未播种取数两分支加 violation_handler 记录位+release 下 return null 空引用即刻崩(fail-fast 传导,合法路径不可达)——debug 下 assert 先中断函数本体两态不可判别,故记录位是唯一可观测面;⑦board_generator/reward_economy 各加 fatal_handler 注入位并由组装点接 orchestrator._fatal(release 剥 assert 后仍经 battle_result 封印真中止)。新件 tests/unit/core/run_time_fatal_test.gd(manifest 登记 expect=1 negative=true):wr5 协作件 _fatal 经组装点传导 p5 封印+缺省形态不外溢/wr6 未知标签通道/wr7 未播种通道(各用新建 RngService 实例,播种断言 _counter==0)。wr10 三条入 variant_placement_test=判定面夹具白盒装载(现网数据无 bias_rewards 行,沿 tree_rules_v11_test 先例)+接线同源+权重生效 77+4*2。验收:variant_placement 49 checks 全绿(wr10 ①②③ PASS:空订阅 0/命中 1 行/装载后 2;查询口有效且与宿主同源;偏运池实测 85);run_time_fatal_test 退出码 1 三点绿;pacing_queue 绿(wr4 前置夹具真入队 2 行→更替后清零);ui_click_probe 问题 0(wr2 遮挡账开/关两侧断言);round_flow_skill_pool 130 checks 绿;wr11 dump_battle 六组(L{1,2}×S{42,779401,779501})与改前 before_* 逐字节 cmp 全等;gdstyle 基线外新违规 0、恶化 1(level_map_screen 类变量 22>21=iter38 存量非本批触碰面)、基线文件零改动〔结构小件批 V15〕

This commit is contained in:
DKChan committed 2026-10-27 18:39:53 +08:00
1 parent 3a20a40891
commit ea322599f7
14 files changed
+211 -27

No files matched your search

+12 -1
View File
@@ -23,7 +23,7 @@ var damage: DamageController
var emit_cb: Callable # 宿主 _emit_row——行协议面单点(5 参 head 束形:head/ri/display/value/extra)
var facts_cb: Callable # 宿主 _fx_host_fact——round_index/battle_index/seals_count/nest_count/hp_ratio 五事实宿主侧单点
var grant_cb: Callable = Callable() # 揭示兑付回调=RewardGrant 授予面(bind_grant 注入;构造序解法——本件对授予面零强引用)
var engine: EffectEngine # 效果引擎(原编排器 _fx——宿主 _init 经此转注 damage/action_economy/reward_economy 三 set_fx)
var engine: EffectEngine # 效果引擎(原编排器 _fx——宿主 _init 经此转注 damage/action_economy 两 set_fx;reward_economy 经 luck_bias_for 查询口取回偏运合计)
var counters_ctx: EffectContext # 四桶引用束(round/battle 两桶本件自有;adventure/level 桶 begin_battle mount_buckets 挂引用)
var ac := {"base": -1, "round": 0, "battle": 0} # ac 束(base=主角 AC 基线快照 enc.hero_armor_class,-1=表值兜底未解析;round=ac_bonus 本轮累积器〔封印桩,round_start 清零〕;battle=本战累积器〔石肤,cap 封顶,begin_battle 清零〕)
var _fx_bonus_delta := {"atk": 0, "max_hp": 0, "armor_class": 0, "ap": 0} # 本战 bonus_delta 累积(战末宿主 bonus_delta_drain 读后清零)
@@ -55,6 +55,17 @@ func fx_emit(event: String, payload: Dictionary) -> Array:
return engine.dispatch(counters_ctx, event, payload, _fx_fact)
# 偏运权重查询(reward_roll 发射面——bias_rewards 词汇在本层收口,掷格域只见整数)。
# 三参形 dispatch(不带 facts:本事件订阅行 when 事实面不参与,命中集与缝拆前逐字同);
# 发射时点由掷格件在开流之后、权重装配之前调用;零命中=0=原行集零扰动。
func luck_bias_for(cell_count: int) -> int:
var total := 0
for h in engine.dispatch(counters_ctx, "reward_roll", {"polarity": "positive", "cell_count": cell_count}):
if String(h.get("kind", "")) == "bias_rewards":
total += int(h.get("value", 0))
return total
# round_start 发射+施加(grant_ap mode:queue=当轮入队,行动经济轮切换即兑现;计数器 round_start
# 重置点在 dispatch 内生效。调用点两处:begin_battle 首轮 / 轮始段续轮。payload 携 round〔宿主侧
# 事实单点〕+ap_exhausted_last〔一滴不剩 when 面〕;发射前 ac_bonus 本轮累积器清零并同步主角 AC)
+2 -1
View File
@@ -211,6 +211,7 @@ func _init(db_ref: ConfigDb, rng_ref: RngServiceCore) -> void:
_enemy_system = UnitContainer.new(db)
_status_effects = StatusContainer.new(db)
_reward_economy = RewardEconomy.new(db, rng)
_board_generator.fatal_handler = _fatal; _reward_economy.fatal_handler = _fatal # 协作件违约→本类 _fatal 封印(单点接线)
_damage = DamageController.new(db, rng, _enemy_system, _status_effects)
_damage.emit_row_cb = _emit_row # 行协议归属本类(9 类行协议 + 来源断言不外泄)
_fx_host = BattleFxHost.new({"db": db, "rng": rng, "minesweeper": minesweeper, "action_economy": action_economy,
@@ -221,7 +222,7 @@ func _init(db_ref: ConfigDb, rng_ref: RngServiceCore) -> void:
_fx_host.bind_grant(_reward_grant.reveal_redeem) # 构造序禁环:两件建齐后接线(fx 件对授予面走注入回调)
_damage.set_fx(_fx_host.engine, _fx_host.counters_ctx) # 效果引擎注入(attack_commit/clamp_check/armor_roll/kill/damage_taken 发射面)
action_economy.set_fx(_fx_host.engine, _fx_host.counters_ctx) # dig_paid/charge_full 发射面
_reward_economy.set_fx(_fx_host.engine, _fx_host.counters_ctx) # reward_roll 发射面
_reward_economy.luck_bias_query = _fx_host.luck_bias_for # 偏运查询口注入(reward_roll 发射归 fx 宿主)
minesweeper.cell_revealed.connect(_on_cell_revealed)
minesweeper.seal_judged.connect(_on_seal_judged)
minesweeper.round_end_board.connect(_on_round_end)
+6
View File
@@ -7,6 +7,10 @@ extends RefCounted
const METRIC_VERSION := 1
# 违约中止通道——缺省空 Callable 退化 push_error+assert(现行为逐字保持);组装层注入
# orchestrator._fatal,使 release 剥 assert 后仍经 battle_result 封印真中止。
var fatal_handler: Callable = Callable()
# ==================== 生成入口 ====================
@@ -395,4 +399,6 @@ func _lex_less(a: Array, b: Array) -> bool:
func _fatal(msg: String) -> void:
push_error("[棋盘生成/fatal] " + msg)
if fatal_handler.is_valid():
fatal_handler.call(msg) # 组装层注入 orchestrator._fatal(封印传导,不绕第二中止通道)
assert(false, msg)
+12 -14
View File
@@ -7,6 +7,9 @@ extends RefCounted
var db: ConfigDb
var rng: RngServiceCore
# 违约中止通道——缺省空 Callable 退化 push_error+assert(现行为逐字保持);组装层注入
# orchestrator._fatal,使 release 剥 assert 后仍经 battle_result 封印真中止。
var fatal_handler: Callable = Callable()
var _phase := "unrolled" # unrolled → ready → retired
var _eligible: Array[Dictionary] = [] # [{cell}] 行主序规范序
var _mapping := {} # Vector2i → reward_id(正向行身份——格面资源类型由 cell_type 承载)
@@ -16,14 +19,9 @@ var _granted := {} # Vector2i → 快照(重复受理幂等返
var _clear_identity := ""
var _clear_granted := false
var _clear_snapshot := {}
# 效果引擎(reward_roll 发射面;偏运硬币 bias_rewards 订阅面)
var _fx: EffectEngine = null
var _ctx: EffectContext = null
func set_fx(fx: EffectEngine, ctx: EffectContext) -> void:
_fx = fx
_ctx = ctx
# 偏运权重查询口(reward_roll 发射归 BattleFxHost 效果层——掷格域不持效果引擎/上下文;
# 参数=本次可掷格数、返回=偏运权重加算量、缺省空回调=恒 0=原行集零扰动)
var luck_bias_query: Callable = Callable()
func _init(db_ref: ConfigDb, rng_ref: RngServiceCore) -> void:
@@ -60,13 +58,11 @@ func roll_board(eligible: Array) -> bool:
_clear_granted = false
_clear_snapshot = {}
var stream: RandomNumberGenerator = rng.open_stream("reward_roll") # 恰一 scope 批(格批 + 清图批尾 + 区间行追加取号)
# reward_roll 发射+施加(格面资源掷定、摇号前权重合成层:
# bias_rewards 订阅命中合计=偏运权重加算(行 value_from magnitude 定影);零命中=原行集零扰动)
# reward_roll 发射归 BattleFxHost(偏运硬币 bias_rewards 订阅命中合计经注入查询口取回);
# 零命中/未接线=0=原行集零扰动
var luck_bias := 0
if _fx != null:
for h in _fx.dispatch(_ctx, "reward_roll", {"polarity": "positive", "cell_count": list.size()}):
if String(h.get("kind", "")) == "bias_rewards":
luck_bias += int(h.get("value", 0))
if luck_bias_query.is_valid():
luck_bias = luck_bias_query.call(list.size())
var cell_rows: Array[Variant] = _biased_cell_rows(luck_bias) # cell 池正向行 weight>0(偏运硬币装配时稀有正向 kinds 权重 +N——池结构零触碰)
var clear_rows: Array[Variant] = _pool_rows("clear_default")
# ① 身份批:每非封锁格恰一类型身份(雷安同池——同一行集同一权重分布)
@@ -365,4 +361,6 @@ func _diag(msg: String) -> void:
func _fatal(msg: String) -> void:
push_error("[地图战斗资源/fatal] " + msg)
if fatal_handler.is_valid():
fatal_handler.call(msg) # 组装层注入 orchestrator._fatal(封印传导,不绕第二中止通道)
assert(false, msg)
+9
View File
@@ -24,6 +24,9 @@ var _master_seed: int = -1 # -1 = 未播种(取数即致命,
var master_seed: int:
get: return _master_seed
var _counter: int = 0 # 全局取数计数器(唯一账本——快照契约 = 主种子 + 本计数器)
# 违约通道(未知用途标签/未播种取数两分支共用)——缺省空 Callable 退化 push_error+assert(现行为逐字保持);
# 注入后供负面套件断言「handler 被调用」(assert 只中断本函数,debug 下两态不可判别——记录位是唯一可观测面)。
var violation_handler: Callable = Callable()
# 事件日志(丙案新增):每冒险一会话,逐次取数落一行(scope/用途标签/派生种子)——不致命、失败静默降级
var _log_path := ""
var _log_fa: FileAccess = null
@@ -100,10 +103,16 @@ func pure_stream(seed_val: int, scope: int) -> RandomNumberGenerator:
func open_stream(purpose: String) -> RandomNumberGenerator:
if not PURPOSE_TAGS.has(purpose):
push_error("[RngService] 未知用途标签: %s" % purpose)
if violation_handler.is_valid():
violation_handler.call(purpose)
assert(false, "未知用途标签(标签词表封闭,EC12)")
return null # release 剥 assert 后经调用方空引用即刻崩=fail-fast 传导(合法路径不可达)
if _master_seed < 0:
push_error("[RngService] 未设 master_seed 即取数(EC7——冒险结构 未接线的显式暴露)")
if violation_handler.is_valid():
violation_handler.call(purpose)
assert(false, "未播种取数致命(EC7)")
return null # 同上(EC7 通道——release 下禁静默发号)
var scope: int = _counter
_counter = scope + 1
var rg := RandomNumberGenerator.new()