extends Node
## GATE — the Atmosphere panel's fog controls (atmosphere audit 2026-10-06).
## F1 a "Layered fog" section with the ten fog_model-1 controls
## F2 a slider drives the SkyDome property (fog_far_end)
## F3 wide-range sliders are LOG (exp_edit) — fog_far_end, fog_near_density
## F4 values read: a density of 3.3e-4 is not shown as "0.000"
## F5 reopening the panel re-reads a value the map wrote to the sky directly
##
## env -u CI HYPERTPS_DAEMON_TCP=127.0.0.1:1 DISPLAY=:0 "$HYPER_TPS_GODOT" --path . \
## res://scenes/test/gate_sky_panel_fog.tscn
var _fails := 0
var _checks := 0
func _p(c: bool, m: String, got: Variant = "") -> void:
_checks += 1
print(("ok " if c else "FAIL: ") + m + ("" if str(got) == "" else " (" + str(got) + ")"))
if not c:
_fails += 1
func _ready() -> void:
_run.call_deferred()
func _run() -> void:
var game: Node = (load("res://scenes/game/game.tscn") as PackedScene).instantiate()
get_tree().root.add_child(game)
for i in 30:
await get_tree().process_frame
var panel: Node = game.get("_sky_debug_panel")
if panel == null and game.has_method("_toggle_sky_debug"):
game.call("_toggle_sky_debug")
await get_tree().process_frame
panel = game.get("_sky_debug_panel")
_p(panel != null, "the Atmosphere panel exists")
if panel == null:
return _end()
var sliders: Dictionary = panel.get("_sliders")
var labels: Dictionary = panel.get("_labels")
var dome: Node = game.get_node("Sky3DExtended/SkyDome")
var want := ["fog_model", "fog_near_density", "fog_far_begin", "fog_far_end", "fog_far_curve",
"fog_far_max", "fog_height_base", "fog_height_falloff", "fog_height_density", "fog_haze_color_depth"]
var missing: Array = want.filter(func(k: String) -> bool: return not sliders.has(k))
_p(missing.is_empty(), "F1 the layered-fog controls exist", missing)
(sliders["fog_far_end"] as HSlider).value = 12345.0
_p(is_equal_approx(float(dome.get("fog_far_end")), 12345.0), "F2 the far-end slider drives SkyDome.fog_far_end", dome.get("fog_far_end"))
_p((sliders["fog_far_end"] as HSlider).exp_edit and (sliders["fog_near_density"] as HSlider).exp_edit,
"F3 wide-range sliders are logarithmic")
(sliders["fog_density"] as HSlider).value = 0.00033
var txt := String((labels["fog_density"] as LineEdit).text)
_p(txt != "0.000" and txt.to_float() > 0.0003, "F4 a density of 3.3e-4 reads as a number", txt)
# The map writes the sky directly; the panel must show it on the next open.
dome.set("fog_far_begin", 777.0)
panel.visible = false
panel.visible = true
await get_tree().process_frame
_p(is_equal_approx((sliders["fog_far_begin"] as HSlider).value, 777.0), "F5 reopening re-reads a value written to the sky",
(sliders["fog_far_begin"] as HSlider).value)
_end()
func _end() -> void:
print("GATE sky_panel_fog: %s (%d checks, %d failed)" % ["PASS" if _fails == 0 else "FAIL", _checks, _fails])
get_tree().quit(0 if _fails == 0 else 1)