# W1/W2 headless 冒烟:加载 A1,打印 load report + sample_height + 顶视截图。 # godot --headless --path project --script world_probe.gd extends SceneTree func _init() -> void: var assets: String = AssetRoot.path() var w: Node = ClassDB.instantiate("Metin2World") if w == null: push_error("Metin2World not registered") quit(1) return w.set("assets_root", assets) w.set("map_path", "OutdoorA1/metin2_map_a1") w.set("auto_load", false) get_root().add_child(w) var ok: bool = w.call("load_map") var rep: Dictionary = w.call("get_load_report") print("load_map ok=", ok) for k in rep: print(" ", k, " = ", rep[k]) var terr: int = 0 for c in w.get_children(): if String(c.name).begins_with("Terrain_"): terr += 1 print("terrain MeshInstance3D children: ", terr) var h1: float = w.call("sample_height", 128.0, 128.0) var h_out: float = w.call("sample_height", -50.0, -50.0) print("sample_height(128,128) = ", h1, " off-map = ", h_out) # 顶视正交截图(W2 与 minimap 对齐用) _shot(w, rep) var expect: int = int(rep["map_size_x"]) * int(rep["map_size_y"]) var pass_ok: bool = ok and terr == expect and int(rep["chunks_failed"]) == 0 \ and h1 != 0.0 and h_out == 0.0 print("RESULT: ", "PASS" if pass_ok else "FAIL") quit(0 if pass_ok else 1) func _shot(w: Node, rep: Dictionary) -> void: var msx: float = float(rep["map_size_x"]) * 256.0 var msy: float = float(rep["map_size_y"]) * 256.0 var cam := Camera3D.new() cam.projection = Camera3D.PROJECTION_ORTHOGONAL cam.size = max(msx, msy) * 1.05 cam.position = Vector3(msx * 0.5, 2000.0, msy * 0.5) cam.rotation_degrees = Vector3(-90.0, 0.0, 0.0) cam.far = 5000.0 get_root().add_child(cam) cam.make_current() var sun := DirectionalLight3D.new() sun.rotation_degrees = Vector3(-55.0, 35.0, 0.0) get_root().add_child(sun) var env := WorldEnvironment.new() var e := Environment.new() e.background_mode = Environment.BG_COLOR e.background_color = Color(0.1, 0.1, 0.12) e.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR e.ambient_light_color = Color(0.5, 0.5, 0.5) env.environment = e get_root().add_child(env) await process_frame await process_frame await process_frame var img := get_root().get_texture().get_image() if img != null: var p := ProjectSettings.globalize_path("res://../test/golden/world-a1-terrain-top.png") DirAccess.make_dir_recursive_absolute(p.get_base_dir()) img.save_png(p) print("screenshot -> ", p)