Boss 战修复(Plan B,用户拍板): - HP 公式 15xPxhall_factor -> HP = P x boss_army_seconds_n(S=23.0→28.0 递增, 每场军列约 23-28 秒清空,战斗时长成为可直接书写的设计旋钮,结构性消除 高殿 P 抵消导致不可胜的旧 bug);hall_factor 降级为纯叙事/视觉参数 - 新增 souls_par 列(0→90000):开场冲锋 intro_dmg = HP x 10% x clamp(souls/souls_par,0,1), 上限 20%->10%;删 hp_factor/intro_dmg_souls_factor/intro_dmg_cap_ratio 三列 - 点击伤害 P x κ x combo_mult,κ = (0.010 + 0.052 x click_ratio) x (1 + 0.30 x m06_owned), click_ratio = 已购点击升级 / 12(κ 0.010→0.0806,满配点击占比约 20.5%±3pp) - 防双重计入:L5-12 点击升级 +1% output/s 留全局区(抬 P 同时抬军列 DPS 与点击 伤害,可接受),不得再计入 κ 分子(recompute 注释固化) 离线契约 v2(P-8,改契约不改表): - OfflineModel.settle 第三参 offline_mult -> offline_add(加法);各档效率 min(rate+add, 1.0) 硬顶 100%,离线永不超在线 - 长明灯 x1.15 乘性 -> +5%/级 加法(满级 +30%,各档封顶 100%) - 0-2h 100% 保持;8h = 6.2 等效小时(77.5% 效率) - Gate #9 拆 9a/9b/9c:9a FAIL->PASS(0-2h 全额 + 8h∈[5.5,6.5]), 9b 长明灯满级 8h∈[7.5,8.0] 且 ≤100%,9c 任意配置效率 ≤100% 数据与工具: - gen_balance_sheets.py 补登 W3 遗留 7 行 tune(防重跑静默丢失),self_check 更新 - boss_battles/upgrades schema 同步(offline_mult->offline_add enum,漏改会违反导入) 测试(runner 7->8 用例,Node 交叉验证 145 断言全过): - 可胜性哨兵重写为「十殿全可胜」:每殿 S_n<30、军列+点击≥HP、余时∈[2,8]、 满配余时差≥4、点击占比∈[15,25]、H10≈20.5%±3pp - κ 四档断言(0.010/0.036/0.062/0.0806,分母 12) - 新增 test_offline_contract.gd:契约 v2 数值面 + 9a/9b/9c 全 PASS + β 缓议
46 lines
2.7 KiB
GDScript
46 lines
2.7 KiB
GDScript
extends RefCounted
|
||
|
||
# 用例:BalanceData 载入 + 跨表引用 + CSV/Bible 关键值(数据门)
|
||
|
||
func run(a, data) -> void:
|
||
a.true_(data.load_errors.is_empty(), "load_errors 为空(%s)" % str(data.load_errors))
|
||
a.eq(data.generators.size(), 12, "12 班底")
|
||
a.eq(data.upgrades.size(), 108, "108 升级")
|
||
a.eq(data.meta_upgrades.size(), 12, "12 宿慧商品")
|
||
a.eq(data.halls.size(), 10, "10 殿")
|
||
a.eq(data.palettes.size(), 10, "10 色板")
|
||
a.eq(data.bosses.size(), 10, "10 殿王战")
|
||
a.eq(data.events.size(), 4, "4 事件")
|
||
# 关键数值(Balance Bible v1.0 逐值一致)
|
||
a.near(data.generators[11].base_rate, 1073741824.0, 0.5, "gen12 rate = 8^10")
|
||
a.near(data.generators[1].payback_seconds(), 120.0, 0.5, "gen2 回本 120s")
|
||
a.near(data.generators[5].payback_seconds(), 293.0, 0.5, "gen6 回本 293s")
|
||
a.near(data.generators[11].payback_seconds(), 1118.0, 0.5, "gen12 回本 1118s")
|
||
a.near(data.hall_by_no(1).gate_merit, 2000.0, 0.5, "H1 门 2K")
|
||
a.near(data.hall_by_no(10).gate_merit, 1.5e9, 0.5, "H10 门 1.5B")
|
||
a.true_(data.hall_by_no(10).is_prestige_gate, "H10 = prestige 门")
|
||
a.near(data.boss_for_hall("hall_01_qinguang").boss_army_seconds, 23.0, 1e-9,
|
||
"H1 殿王军列单推秒数 S_1 = 23(方案 B;旧 HP 系数 15 已废止)")
|
||
a.near(data.boss_for_hall("hall_10_zhuanlun").boss_army_seconds, 28.0, 1e-9,
|
||
"H10 殿王军列单推秒数 S_10 = 28")
|
||
a.eq(data.boss_for_hall("hall_01_qinguang").souls_par, 0, "H1 超度基准 0(无开场加成)")
|
||
a.eq(data.boss_for_hall("hall_10_zhuanlun").souls_par, 90000, "H10 超度基准 90000")
|
||
# 敕封诏书(P-12:requires = enthrone_ready)
|
||
var edict := data.upgrade("up_gate_tianzi")
|
||
a.true_(edict != null, "敕封诏书存在")
|
||
a.eq(edict.requires, "enthrone_ready", "诏书 requires = enthrone_ready")
|
||
a.eq(edict.cost, 800000000000, "诏书成本 800B")
|
||
# 调参数(balance_tuning)
|
||
a.near(data.tune_num("tune_souls_div", 0.0), 10000.0, 1e-9, "超度除数 10000")
|
||
a.near(data.tune_num("tune_enthrone_suihui_req", 0.0), 60.0, 1e-9, "敕封宿慧门槛 60")
|
||
a.near(data.tune_num("tune_enthrone_rebirths", 0.0), 2.0, 1e-9, "敕封转世门槛 2")
|
||
a.eq(data.tune_text("tune_restart_curve", ""), "1:0.6:0.4:0.3", "重开曲线文本")
|
||
a.near(data.tune_num("tune_wrath_layers", 0.0), 22.0, 1e-9, "冤煞 22 层")
|
||
a.near(data.tune_num("tune_click_base", 0.0), 1.0, 1e-9, "点击基础值 1")
|
||
# 跨表引用完整性(schema 管单表;这里查跨表)
|
||
a.true_(data.check_references().is_empty(), "跨表引用无悬挂(%s)" % str(data.check_references()))
|
||
# 每殿恰一场殿王战 + 色板
|
||
for h in data.halls:
|
||
a.true_(data.boss_for_hall(h.id) != null, "%s 有 boss 行" % h.id)
|
||
a.true_(data.palette_for_hall(h.id) != null, "%s 有色板行" % h.id)
|