- CLAUDE.md 硬性红线新增「文件头零工作日志」;code-conventions.md 新增 §1.4.1(含反面案例) - 全仓 .gd 文件头注清偿:删除全部带日期条目、批次叙事段与迁移退役叙述,保留并改写为 现在时的职责、接口契约、GDD 锚内容(main.gd 头注 42→31 行、save_manager.gd 49→45 行) - 纯注释改动零行为变更,按用户令免测试免冒烟
61 lines
2.7 KiB
GDScript
61 lines
2.7 KiB
GDScript
# VERTICAL SLICE - NOT FOR PRODUCTION
|
|
# 定位:分析工具·非验收件——零断言取数工具,不出入任何闸。
|
|
# Date: 2026-09-19
|
|
# 技能池节奏探针:地精一伙 (1,1) 750 出招零突刺异常的定位——
|
|
# ① 表侧:resolve_enemy_rowset(1,1) 的池快照内容;
|
|
# ② 摇号侧:隔离 SkillLottery.draw 大样本份额;
|
|
# ③ 战斗侧:真实 (1,1) 战斗逐执行行按 skill_id 计数。
|
|
# 运行:Godot_console.exe --headless --path . --script res://smoke/skill_rhythm_probe.gd
|
|
extends SceneTree
|
|
|
|
const BattleDriver := preload("res://smoke/battle_driver.gd") # T6 收口:挖掘驱动循环单点(策略仍归 AutoPlayer 单一实现)
|
|
|
|
func _initialize() -> void:
|
|
var db = load("res://core/config_db.gd").new()
|
|
db.load_tables("res://data/tables", false)
|
|
|
|
# ① 表侧(2026-10-07 行集多行批 T2 机械适配——行集数组取首行,零内容期行为零变化)
|
|
var row = db.resolve_enemy_rowset(1, 1)[0]
|
|
print("[1] row(1,1) display=", row.get("display_name"), " unit_count=", row.get("unit_count"),
|
|
" pool=", row.get("pool"))
|
|
|
|
# ② 摇号侧隔离
|
|
var rng = load("res://core/rng_service.gd").new()
|
|
rng.set_master_seed(20260919)
|
|
var lot = load("res://core/skill_lottery.gd")
|
|
var counter := {}
|
|
for i in range(10000):
|
|
var stream: RandomNumberGenerator = rng.open_stream("behavior_roll")
|
|
var s: String = lot.draw(row.get("pool"), stream)
|
|
counter[s] = counter.get(s, 0) + 1
|
|
print("[2] SkillLottery 10000 抽(统一流顺序取号——并流后子流复用退役): ", counter)
|
|
|
|
# ③ 战斗侧(真实路径):(1,0) 对照 + (1,1) 异常组
|
|
for depth in [0, 1]:
|
|
var casts := {}
|
|
var battles := 0
|
|
for i in range(10):
|
|
var r = _run_battle(db, 4200 + i, 1, depth, casts)
|
|
battles += 1
|
|
print("[3] 战斗侧 (1,%d) %d 场执行出招 skill_id 计数: " % [depth, battles], casts)
|
|
quit(0)
|
|
|
|
|
|
func _run_battle(db, seed_val: int, L: int, depth: int, casts: Dictionary) -> Dictionary:
|
|
var rng = load("res://core/rng_service.gd").new()
|
|
rng.set_master_seed(seed_val)
|
|
var settlement = load("res://core/battle_orchestrator.gd").new(db, rng)
|
|
var out := {"result": ""}
|
|
settlement.battle_finished.connect(func(payload): out.result = payload.get("result", ""))
|
|
settlement.step_row.connect(func(row):
|
|
if row.type == "damage" and row.source_class == "enemy_action":
|
|
var sid: String = str(row.get("skill_id", "?"))
|
|
casts[sid] = casts.get(sid, 0) + 1)
|
|
if not settlement.begin_battle({"level_index": L, "node_depth": depth, "hero_hp": int(db.hero.max_hp)}):
|
|
return out
|
|
var guard_rounds := 40
|
|
while out.result == "" and guard_rounds > 0:
|
|
guard_rounds -= 1
|
|
BattleDriver.drive_round(settlement, func() -> bool: return out.result == "")
|
|
return out
|