From a4edb1e7f80de2dc0e85770ce3d49c15bcfdf9ed Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Wed, 23 Sep 2026 05:37:50 +0800 Subject: [PATCH] =?UTF-8?q?feat(balance):=20=E5=85=B3=E9=97=B4=E5=A4=A7?= =?UTF-8?q?=E5=A5=96=E5=8A=B1=2010=E2=86=925=20+=20L2=20=E4=BA=94=E5=A4=84?= =?UTF-8?q?=E8=A1=80=E9=87=8F=E6=94=B6=E7=B4=A7=E2=80=94=E2=80=94=E5=8F=8C?= =?UTF-8?q?=E5=90=88=E6=A0=BC=E7=BA=BF=E6=89=AB=E6=8F=8F=E6=94=B6=E6=95=9B?= =?UTF-8?q?=EF=BC=88=E7=94=A8=E6=88=B7=E6=8B=8D=E6=9D=BF=202026-09-23?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - adventure.tres: level_clear_hp_bonus 10→5(刀一:关间补给收窄) - enemy.tres L2: 群行 22→26×3 / 24→28、蛛化卓尔精灵 112→130(刀二=B包第7轮留档收紧候选L2部分;L3 未动) - smoke_all.gd: 满配锚 (400,200)→(900,400)——L2 抬血后旧档不再满通,先例式抬锚(B包 200/100→400/200 同款) - 读数:零强化过第二关率 普通 15→2% / 完美 40→15%;营地循环爬升形态成立(第4局0%→第37局100%) - 冒烟 553 项 0 失败三闸过;verifier 双轮扫描报告 production/qa/balance-verifier-20260923-043341/050222.md(worktree) --- .../data/tables/adventure.tres | 2 +- .../data/tables/enemy.tres | 22 +++++++++---------- .../smoke/smoke_all.gd | 22 +++++++++---------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/prototypes/dungeon-sweeper-vertical-slice/data/tables/adventure.tres b/prototypes/dungeon-sweeper-vertical-slice/data/tables/adventure.tres index 9b5e5e64..ddf9750c 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/data/tables/adventure.tres +++ b/prototypes/dungeon-sweeper-vertical-slice/data/tables/adventure.tres @@ -4,7 +4,7 @@ [resource] script = ExtResource("1") -level_clear_hp_bonus = 10 +level_clear_hp_bonus = 5 keystone_per_level = 10 ; 冒险结构实现批(2026-09-21 建表——registry adventure_table 条目同批注记更新): diff --git a/prototypes/dungeon-sweeper-vertical-slice/data/tables/enemy.tres b/prototypes/dungeon-sweeper-vertical-slice/data/tables/enemy.tres index 641eb4fb..e866e9ab 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/data/tables/enemy.tres +++ b/prototypes/dungeon-sweeper-vertical-slice/data/tables/enemy.tres @@ -140,7 +140,7 @@ rows = [{ "display_name": "熊地精猎群", "unit_count": 2, "unit_count_max": 3, - "hp": 22, + "hp": 26, "atk": 2, "atk_min": 1, "atk_max": 3, @@ -162,7 +162,7 @@ rows = [{ "enemy_id": "giant_spider", "display_name": "巨蜘蛛", "unit_count": 2, - "hp": 24, + "hp": 28, "atk": 2, "atk_min": 1, "atk_max": 3, @@ -205,10 +205,10 @@ rows = [{ "node_depth": 6, "enemy_id": "giant_spider", "display_name": "巨蜘蛛巢群", - "unit_count": 2, - "unit_count_max": 3, - "hp": 22, - "atk": 1, + "unit_count": 2, + "unit_count_max": 3, + "hp": 26, + "atk": 1, "atk_min": 1, "atk_max": 2, "pool": [{ @@ -228,10 +228,10 @@ rows = [{ "node_depth": 7, "enemy_id": "giant_spider", "display_name": "巨蜘蛛巢群", - "unit_count": 2, - "unit_count_max": 3, - "hp": 22, - "atk": 2, + "unit_count": 2, + "unit_count_max": 3, + "hp": 26, + "atk": 2, "atk_min": 1, "atk_max": 3, "pool": [{ @@ -252,7 +252,7 @@ rows = [{ "enemy_id": "drider", "display_name": "蛛化卓尔精灵", "unit_count": 1, - "hp": 112, + "hp": 130, "atk": 3, "atk_min": 2, "atk_max": 4, diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd index 9bfdea57..36322a49 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd @@ -124,7 +124,7 @@ func _smoke_adventure_table() -> void: func _smoke_adventure_api() -> void: print("--- 冒险结构 API 闸(重复开始拒绝 · 放弃两态受理)---") var adr = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(42)) - adr.set_hero_override(400, 200) # 首战速胜档(放弃的非战斗受理要走到选路态) + adr.set_hero_override(900, 400) # 首战速胜档(放弃的非战斗受理要走到选路态) check(adr.start_adventure(42), "冒险启动受理(主种子注入恰一次——state=running)") check(not adr.start_adventure(43), "进行中重复 start_adventure 拒绝(重开须待结算完毕)") check(adr.runner().current_battle() != null, "首战在飞(接口①开始关卡直达战斗节点)") @@ -170,10 +170,10 @@ func _smoke_adventure() -> void: miss += 1 check(miss == 0, "行集内每个战斗/Boss 节点在 board_gen + enemy 有精确行(缺失 %d)" % miss) # ② 满配通关 + ④ 大奖励兑付(恰 2 次 · 读数=表值 · 回满=新上限 · 覆盖值通道传播 L2/L3 首战上限) - var st: Dictionary = autoplay.run_adventure(_db, 42, 400, 200) + var st: Dictionary = autoplay.run_adventure(_db, 42, 900, 400) var sum: Dictionary = st["summary"] check(String(st["result"]) == "completed" and bool(sum.get("cleared", false)), - "满配通关(42 / atk+400 / hp+200——cleared=true;v2 怪阶梯后旧 200/100 档不再满配)") + "满配通关(42 / atk+900 / hp+400——cleared=true;v2 怪阶梯后旧 200/100 档不再满配)") check(int(sum.get("levels_cleared", -1)) == 3, "通关几关 = 3(levels_cleared)") check(int(sum.get("keystone_total", -1)) == 3 * int(_db.adventure.keystone_per_level), "钥石合计 = 3 × keystone_per_level(%d)" % int(sum.get("keystone_total", -1))) @@ -191,7 +191,7 @@ func _smoke_adventure() -> void: reward_ok = false check(reward_ok, "大奖励读数:hp_bonus=表值 · 新上限累加 · 回满=新上限 · 钥石逐关注账") var seq: Array = st["encounter_max_hp_seq"] - var k := 3.0 # hp+200 ⇒ TunePanel 百分比后乘 ×3(加算先加、百分比后乘——生效次序口径) + var k := 5.0 # hp+400 ⇒ TunePanel 百分比后乘 ×5(加算先加、百分比后乘——生效次序口径) var exp_base := maxi(1, int(round(float(int(_db.hero.max_hp)) * k))) var exp_l2 := maxi(1, int(round(float(int(_db.hero.max_hp) + hp_bonus) * k))) var exp_l3 := maxi(1, int(round(float(int(_db.hero.max_hp) + 2 * hp_bonus) * k))) @@ -202,7 +202,7 @@ func _smoke_adventure() -> void: check(idx_l2 > 0 and idx_l3 > idx_l2, "L2/L3 首战上限入参 = 基础+加算(%d→%d——大奖励经覆盖值通道传播)" % [exp_l2, exp_l3]) # ③ 种子域可复现(同种子两局:summary + 上限序列 + 行进序列逐位一致) - var st2: Dictionary = autoplay.run_adventure(_db, 42, 400, 200) + var st2: Dictionary = autoplay.run_adventure(_db, 42, 900, 400) check(st2["summary"] == sum and st2["encounter_max_hp_seq"] == seq and st2["visited_ids"] == st["visited_ids"], "同种子两局逐位可复现(summary/上限序列/行进序列——主种子单点派生)") @@ -242,7 +242,7 @@ func _smoke_adventure() -> void: "L2 败北败退明细:层号=2 · 节点在案(数值验证取数面 2026-09-22)") # ⑥ 重复宣布拒绝(settle 后再调 _on_level_finished——摘要零变化) var adr6 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(7)) - adr6.set_hero_override(400, 200) + adr6.set_hero_override(900, 400) check(adr6.start_adventure(7), "重复拒绝场景:冒险启动(seed 7)") var b6 = adr6.runner().current_battle() var st6 := _adv_st() @@ -273,7 +273,7 @@ func _smoke_adventure() -> void: var same := {} for s in range(42, 92): var a8 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(s)) - a8.set_hero_override(400, 200) + a8.set_hero_override(900, 400) if not a8.start_adventure(s): continue if _adv_drive_to_shop(a8, _adv_st(), autoplay): @@ -313,7 +313,7 @@ func _smoke_adventure() -> void: "同一公式两个落点逐位一致(LevelRunner.rest_heal_amount 内置默认)") # ⑩ 放弃(战斗中拒绝 · 非战斗期受理同失败型结算) var a10 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(15)) - a10.set_hero_override(400, 200) + a10.set_hero_override(900, 400) check(a10.start_adventure(15), "放弃场景:冒险启动(seed 15——首战在飞)") check(not a10.abandon(), "战斗中 abandon 拒绝(战斗域单事务在飞)") var b10 = a10.runner().current_battle() @@ -2907,7 +2907,7 @@ func _smoke_shop_room() -> void: var shop_run := {} for s in range(42, 92): var runner = load("res://core/level_runner.gd").new(_db, _fresh_rng(s)) - runner.set_hero_override(400, 200) # 行进段快速通关档(购买断言与百分比轴正交——加算区单独断言) + runner.set_hero_override(900, 400) # 行进段快速通关档(购买断言与百分比轴正交——加算区单独断言) runner.start_level(2, s) var st := {"result": "", "rounds": 0, "refreshes": 0, "mine_hits": 0, "hero_dmg": 0, "policy": "normal"} var guard := 40 @@ -3481,7 +3481,7 @@ func _smoke_save() -> void: # ⑨ 摘要集成(冒险结构批产物驱动):run_adventure 真局摘要 → apply 原语 → 域读数 → 写盘读回保持 var autoplay = load("res://smoke/level_autoplay.gd") - var st9: Dictionary = autoplay.run_adventure(_db, 42, 400, 200) + var st9: Dictionary = autoplay.run_adventure(_db, 42, 900, 400) var f9 = sm_script.new(paths[8]) f9.apply_adventure_summary(st9.get("summary", {})) var kpl := int(_db.adventure.keystone_per_level) @@ -3492,7 +3492,7 @@ func _smoke_save() -> void: "集成三关首杀标记齐") check(f9.recent_summaries().size() == 1 and int(f9.recent_summaries()[0].get("master_seed", -1)) == 42, "集成 recent 1 条且 seed 42") - var st9b: Dictionary = autoplay.run_adventure(_db, 42, 400, 200) + var st9b: Dictionary = autoplay.run_adventure(_db, 42, 900, 400) f9.apply_adventure_summary(st9b.get("summary", {})) check(f9.clear_count(1) == 2 and f9.clear_count(2) == 2 and f9.clear_count(3) == 2, "第二局后通关次数全 2") check(f9.keystone_balance() == 6 * kpl, "第二局后余额翻倍(6 × keystone_per_level)")