迭代14.5调试整合批:主菜单三散件(随机种子/数值调整板/两层调试)收一张调试浮窗DebugOverlay——入口=开始覆盖层右下角「调试」角标(与主按钮组非平级,DS_DEBUG=1门控保留迭代8卡④口径),浮窗=可扩展滚动列表页(种子/数值调整/批量模拟/两层调试四区块,后续项往下追加)悬浮于菜单之上不隐藏开始层(Dialog形态同确认弹窗先例,TunePanel互斥形态退役),仅开始菜单可开(_show_debug_overlay门禁护栏——用户裁对局中不可达),两层调试入口随开随收;TunePanel整体吸收退役(git rm含.uid);探针ui_tune_probe改接+缺陷⑤断言语义翻转(浮窗树序必须在开始层之后)+ui_click_probe两处改接;四拍板P1甲/P2乙/P3仅菜单/P4可扩展列表全落(2026-10-04用户裁);核心/呈现注释TunePanel口径同步调试浮窗(零行为);冒烟747/0+探针tune/click/ui三绿(worktree首跑先--import建类名缓存+主区art资产补拷)

This commit is contained in:
DKChan committed 2026-10-05 00:50:13 +08:00
1 parent 9e1a8beb5e
commit 48c0b343a6
3 files changed
+58 -19

No files matched your search

+247
View File
@@ -0,0 +1,247 @@
# VERTICAL SLICE - NOT FOR PRODUCTION
# Date: 2026-10-04(迭代 14.5 调试整合批——主菜单三散件(随机种子/角色数值调整板/两层调试入口)收一张调试浮窗,
# 原 views/tune_panel.gd 整体吸收退役)
# 开发调试浮窗:入口 = 开始覆盖层右下角「调试」角标(DS_DEBUG=1 门控归组合根)——非主按钮组平级;
# 仅开始菜单可开(浮于菜单之上的 Dialog 形态,不隐藏开始层——与确认弹窗同款;对局中不可达)。
# 列表页形态可扩展:后续调试项按区块往下追加,超高滚动。
# 纯视图边界(规范 1.3):数值应用/批量模拟/对局启动全部经信号外发由组合根承接
#(apply_requested / simulate_requested / debug_levels_requested / closed);
# 模拟进度与报告经 setter 注入——零核心写、不拼报告文案(装配归 HudPresenter)。
# 探针接缝(ADR-0004"合成输入走真实翻译出口"口径):press_apply_for_probe 等三键 = 按钮真实信号路径。
class_name DebugOverlay
extends Control
signal apply_requested(atk_pct: int, hp_pct: int) # 应用并关闭——加成落表归组合根单一应用路径
signal simulate_requested(count: int) # 批量模拟编排归组合根(表基线复位 + 单路径施加)
signal debug_levels_requested # 两层调试对局入口(编排归 debug_session.gd)
signal closed
var seed_edit: LineEdit # 组合根 _seed_value 唯一读取面(原开始覆盖层种子行迁入)
var _db
var _base_atk := 0
var _base_hp := 0
var _atk: HSlider
var _hp: HSlider
var _atk_val: Label
var _hp_val: Label
var _eff: Label
var _sim_count: SpinBox
var _sim_btn: Button
var _sim_out: RichTextLabel
func _init(db_ref, base_atk: int, base_hp: int) -> void:
_db = db_ref
_base_atk = base_atk
_base_hp = base_hp
_build()
_sync_labels()
visible = false # 显式初始化——不靠树序巧合(缺陷⑤家族纪律)
# ---- 对外语义面(组合根/探针)----
func atk_pct() -> int:
return int(_atk.value)
func hp_pct() -> int:
return int(_hp.value)
func set_sliders(atk: int, hp: int) -> void:
_atk.value = atk
_hp.value = hp
func reset_sliders() -> void:
_atk.value = 0
_hp.value = 0
_sync_labels()
func effect_text() -> String:
return _eff.text
func set_sim_count(n: int) -> void:
_sim_count.value = n
func is_running() -> bool:
return _sim_btn.disabled
func set_sim_running(running: bool) -> void:
_sim_btn.disabled = running
_sim_btn.text = "模拟中…" if running else "运行模拟"
func set_sim_progress(text: String) -> void:
_sim_out.text = text
func set_sim_report(text: String) -> void:
_sim_out.text = text
func output_text() -> String:
return _sim_out.get_parsed_text()
# ---- 探针接缝(真实翻译出口——按钮 pressed 信号路径,非直调组合根)----
func press_apply_for_probe() -> void:
_apply_btn_pressed()
func press_reset_for_probe() -> void:
_reset_btn_pressed()
func press_simulate_for_probe() -> void:
_sim_btn.pressed.emit()
# ---- 内部(信号 → 外发)----
func _apply_btn_pressed() -> void:
apply_requested.emit(atk_pct(), hp_pct())
func _reset_btn_pressed() -> void:
reset_sliders()
func effective_atk() -> int:
return UiKit.scaled(_base_atk, atk_pct())
func effective_max_hp() -> int:
return UiKit.scaled(_base_hp, hp_pct())
# ---- 内部构建(标题/关闭固定于浮窗骨架,可扩展列表区居中滚动)----
func _build() -> void:
var shell: Dictionary = UiKit.modal_shell(self, UiKit.BG_OVERLAY, Vector2(640, 0), 8)
var box: VBoxContainer = shell.box
var title := UiKit.label("调试", 26, true, UiKit.WARM)
box.add_child(title)
var desc := UiKit.label(
"开发调试专用——仅开始菜单可开(DS_DEBUG=1 时入口点亮)。\n百分比叠加基础值:攻击 %d / 生命 %d。影响所有模式(手动与模拟),不落盘。" % [_base_atk, _base_hp],
13, false, UiKit.WARM_SOFT)
box.add_child(desc)
box.add_child(HSeparator.new())
# 可扩展列表页(后续调试项按区块往下追加——超高滚动,滚轮下探)
var scroll := ScrollContainer.new()
scroll.custom_minimum_size = Vector2(0, 430)
scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
box.add_child(scroll)
var list := VBoxContainer.new()
list.size_flags_horizontal = Control.SIZE_EXPAND_FILL
list.add_theme_constant_override("separation", 8)
scroll.add_child(list)
# 区块①随机种子(原开始覆盖层种子行迁入——非法定值回退 42 的口径归组合根 _seed_value)
var seed_row := HBoxContainer.new()
list.add_child(seed_row)
seed_row.add_child(UiKit.label("随机种子", 15, false))
seed_edit = LineEdit.new()
seed_edit.text = "42"
seed_edit.custom_minimum_size = Vector2(120, 0)
seed_row.add_child(seed_edit)
list.add_child(HSeparator.new())
# 区块②角色数值调整板(原 TunePanel 内容原样吸收)
var atk_row := _slider_row(list, "攻击加成")
_atk = atk_row.slider
_atk_val = atk_row.value_label
var hp_row := _slider_row(list, "生命加成")
_hp = hp_row.slider
_hp_val = hp_row.value_label
_eff = UiKit.label("", 14, false)
list.add_child(_eff)
var btn_row := HBoxContainer.new()
list.add_child(btn_row)
var apply_btn := UiKit.button("应用并关闭")
apply_btn.pressed.connect(_apply_btn_pressed)
btn_row.add_child(apply_btn)
var reset_btn := UiKit.button("重置为 0")
reset_btn.pressed.connect(_reset_btn_pressed)
btn_row.add_child(reset_btn)
list.add_child(HSeparator.new())
# 区块③批量模拟(与 headless 扫描同口径——编排归 tune_sim_controller)
var sim_row := HBoxContainer.new()
list.add_child(sim_row)
sim_row.add_child(UiKit.label("批量模拟第一关", 15, false))
_sim_count = SpinBox.new()
_sim_count.min_value = 10
_sim_count.max_value = 200
_sim_count.step = 10
_sim_count.value = 30
_sim_count.custom_minimum_size = Vector2(90, 0)
sim_row.add_child(_sim_count)
sim_row.add_child(UiKit.label("次(理性玩家策略,含面板当前加成)", 13, false))
_sim_btn = UiKit.button("运行模拟")
_sim_btn.pressed.connect(_emit_simulate_requested)
sim_row.add_child(_sim_btn)
_sim_out = RichTextLabel.new()
_sim_out.bbcode_enabled = true
_sim_out.custom_minimum_size = Vector2(0, 300)
list.add_child(_sim_out)
list.add_child(HSeparator.new())
# 区块④两层调试对局入口(原开始覆盖层调试按钮迁入——HP 关内延续)
var dbg_btn := UiKit.button("调试 · 连续关卡两层(HP 关内延续)")
dbg_btn.pressed.connect(_emit_debug_levels)
list.add_child(dbg_btn)
var close_btn := UiKit.button("关闭")
close_btn.pressed.connect(_emit_closed)
box.add_child(close_btn)
func _slider_row(box: VBoxContainer, title: String) -> Dictionary:
var row := HBoxContainer.new()
box.add_child(row)
row.add_child(UiKit.label(title, 15, false))
var s := HSlider.new()
s.min_value = 0
s.max_value = 300
s.step = 5
s.custom_minimum_size = Vector2(320, 24)
row.add_child(s)
var v := UiKit.label("+0%", 15, true)
v.custom_minimum_size = Vector2(70, 0)
row.add_child(v)
s.value_changed.connect(_on_slider_value_changed)
return {"slider": s, "value_label": v}
func _sync_labels() -> void:
_atk_val.text = "+%d%%" % atk_pct()
_hp_val.text = "+%d%%" % hp_pct()
_eff.text = "生效值:攻击 %d → %d · 生命 %d → %d" % [
_base_atk, effective_atk(), _base_hp, effective_max_hp()]
func _emit_simulate_requested() -> void:
simulate_requested.emit(int(_sim_count.value))
func _emit_debug_levels() -> void:
debug_levels_requested.emit()
func _emit_closed() -> void:
closed.emit()
func _on_slider_value_changed(_value: float) -> void:
_sync_labels()