extends SceneTree # Headless gameplay test: run with # godot --headless -s res://tests/test_surface_profiles.gd # Forgejo #51: a landed gas giant needs its own background shader instead of # lunar_surface.gdshader recoloured (craters reading as regolith, not # atmosphere). Verifies: # 1. the gas profile resolves a background_shader different from rocky's # 2. PlanetSurfaceController._compose_surface() actually swaps the # background material's shader when landing on a gas giant # 3. landing on a rocky planet ends up on rocky's own declared shader # # Rocky's background_shader used to be left null, meaning "keep whatever the # hosting scene already had". That convention is gone: it resolved to a # different shader in the game than in the setup editor, which is exactly how # the two came apart (see tests/test_surface_background_shared.gd). Every # profile now names its shader, so this checks rocky lands on ITS OWN rather # than on whatever PlanetSurface.tscn shipped with. # # PlanetSurfaceController's _ready() (which calls _compose_surface()) does # not fire synchronously inside add_child() for a -s entry-point script - # it's deferred to the next frame, same as ResourceReadout's was for #49 - # so every read of the composed shader below waits a frame after add_child() # rather than checking on the same one. var game_state: Node var scene_shader: Shader var rocky_shader: Shader var gas_shader: Shader var rocky_shader_after_compose: Shader var scene: Node var stage: int = 0 var elapsed: float = 0.0 func _initialize() -> void: game_state = root.get_node("GameState") # Whatever PlanetSurface.tscn itself ships with, read from the scene # rather than named by path. The property under test is "a null # background_shader leaves the scene's own background alone" - naming a # specific file here instead made this fail the moment the lunar # background changed implementation (#68 swapped the per-pixel # procedural shader for a baked, tiled one), which is a change this test # has no business having an opinion about. var packed: PackedScene = load("res://surface/PlanetSurface.tscn") var probe: Node = packed.instantiate() scene_shader = probe.get_node("BackgroundLayer/Background").material.shader probe.free() # Loaded by path into a local, not referenced by its bare global # class_name - same load-order hazard PlanetSetups.gd and # PlanetSurfaceController.gd already work around: the class_name cache # isn't guaranteed warm before an import pass has run. var surface_profiles: Script = load("res://surface/PlanetSurfaceProfiles.gd") var rocky_profile: Resource = surface_profiles.get_profile("rocky") var gas_profile: Resource = surface_profiles.get_profile("gas") if rocky_profile.background_shader == null: print("TEST_SURFACE_PROFILES: FAIL (rocky profile has no background_shader set)") quit(1) return rocky_shader = rocky_profile.background_shader if gas_profile.background_shader == null: print("TEST_SURFACE_PROFILES: FAIL (gas profile has no background_shader set)") quit(1) return gas_shader = gas_profile.background_shader if gas_shader == scene_shader: print("TEST_SURFACE_PROFILES: FAIL (gas profile points at the scene's own shader, not its own)") quit(1) return game_state.planet_definition_id = "rocky" scene = load("res://surface/PlanetSurface.tscn").instantiate() root.add_child(scene) func _process(delta: float) -> bool: elapsed += delta match stage: 0: if elapsed < 0.2: return false var rocky_bg: ShaderMaterial = scene.get_node("BackgroundLayer/Background").material rocky_shader_after_compose = rocky_bg.shader scene.free() game_state.planet_definition_id = "gas_giant" scene = load("res://surface/PlanetSurface.tscn").instantiate() root.add_child(scene) elapsed = 0.0 stage = 1 return false 1: if elapsed < 0.2: return false var gas_bg: ShaderMaterial = scene.get_node("BackgroundLayer/Background").material scene.free() if rocky_shader_after_compose != rocky_shader: print("TEST_SURFACE_PROFILES: FAIL (landing on a rocky planet did not put rocky's own declared shader on the background)") quit(1) return true if gas_bg.shader != gas_shader: print("TEST_SURFACE_PROFILES: FAIL (landing on a gas giant did not swap in gas_surface.gdshader)") quit(1) return true if gas_bg.shader == scene_shader: print("TEST_SURFACE_PROFILES: FAIL (gas surface still uses the scene's own lunar background)") quit(1) return true print("TEST_SURFACE_PROFILES: PASS") quit(0) return true return false