Files
gplan-2/game/smoke/board_shot_probe.gd
T
DKChan 36f652c63a iter9-numfix-e: L2/L3 数字可读性二次修复——甲案证伪改色牌垫底(渲染帧取证驱动)
- 用户实机复测「还是看不清」+ 追责「未经验证不许报完成」:补 board_shot_probe 渲染帧取证探针
  (窗口化真实 LevelRunner+novice 18 步+BoardView 真渲染+视口 PNG,L1/L2/L3 三关)——
  深墨直画在 underdark 系地板放大后可辨但观感隐形(双峰纹理:近黑斑+近白筋并存,
  任何墨族直画必融一峰)——甲案(按板自适应墨族)证伪
- 修复改三态呈现:dungeon 亮族直画(p90≥4.5/均值≥2.5)/中暗板深墨直画(均值门收紧 3.0)/
  双峰板色牌垫底(素牌+深墨 12:1 纹理免疫——v2 色牌形制复役)
- 目视验证(本会话亲验渲染帧):L2/L3 数字素牌深墨清晰可读,取证图
  artwork/qa-board-shots-20261001/(board_L1/L2/L3 + _zoom_L2 证伪对照)
- 机检同步:terrain_tile_sets_test 三态断言 19/19;art-bible v3.4(三态+目视验证面入流程);
  冒烟断言随新语义更新(雷当量 6/8/8 钉值/大奖励与 L3 上限允许模拟档购血叠加——v3.4 购物
  改变 max_hp 序列语义,非功能回归)
- 轻闸:冒烟 596/0+四探针 PASS;剂量-响应点(slip 半档 N=100)L1 36%/战役 1%——悬崖三点齐
2026-10-01 05:57:12 +08:00

63 lines
2.6 KiB
GDScript

# 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)