# VERTICAL SLICE - NOT FOR PRODUCTION # 棋盘渲染帧取证探针(2026-10-01——数字墨族按板自适应修复的目视验证面:机检≠看得清)。 # 必须**窗口化**运行(headless 无渲染面): # Godot_console.exe --path . res://smoke/board_shot_probe.tscn -- <输出目录> # 流程:L1/L2/L3 各起一板(真实 LevelRunner+settle_batch 驱动 ~18 步 novice——自然揭示数字/旗), # BoardView 真渲染,frame_post_draw 同步后抓视口 PNG。零存档触碰(无 save_manager 引用)。 extends Node const AutoPlayer := preload("res://smoke/auto_player.gd") func _ready() -> void: var args := OS.get_cmdline_user_args() var out := args[0] if args.size() >= 1 and args[0] != "" else "user://board-shots" DirAccess.make_dir_recursive_absolute(out) await get_tree().process_frame var db = load("res://core/config_db.gd").new() var ok: bool = db.load_tables("res://data/tables", true) if not ok: push_error("[board_shot] 表加载失败") get_tree().quit(1) return var ui_font: Font = load("res://presentation/views/ui_kit.gd").load_font(load("res://presentation/views/ui_kit.gd").FONT_UI) var targets := [[1, "L1_dungeon"], [2, "L2_underdark"], [3, "L3_deep_underdark"]] for t in targets: var level_index: int = t[0] var tag: String = t[1] var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(420000 + level_index) var runner = load("res://core/level_runner.gd").new(db, rng) if not runner.start_level(level_index, 420000 + level_index, {}, 0): push_error("[board_shot] 开关失败 level=%d" % level_index) get_tree().quit(1) return var settlement = runner.current_battle() for i in range(18): var act: Dictionary = AutoPlayer.novice_action(settlement.minesweeper) var kind := String(act.get("kind", "stop")) if kind == "stop": break var op := kind if kind == "flag": op = "flag_place" settlement.minesweeper.settle_batch([{"action": op, "cell": act.get("cell")}]) var view = load("res://presentation/views/board_view.gd").new() view.size = Vector2(900, 900) view.position = Vector2(40, 40) if ui_font != null: view.set_world_font(ui_font) add_child(view) view.rebuild(settlement.minesweeper.current_board(), settlement.minesweeper) for i in range(6): await get_tree().process_frame await RenderingServer.frame_post_draw var img := get_viewport().get_texture().get_image() var path := "%s/board_%s.png" % [out, tag] img.save_png(path) print("[board_shot] saved %s (%dx%d)" % [path, img.get_width(), img.get_height()]) view.queue_free() await get_tree().process_frame print("[board_shot] done") get_tree().quit(0)