From 7f753cb1b8dcf32a4fd4d9a7452de5535c3ed473 Mon Sep 17 00:00:00 2001 From: coder-bot Date: Thu, 20 Aug 2026 22:17:48 +0000 Subject: [PATCH 1/5] WIP checkpoint: PC2: Build a basic playable test level scene --- scenes/worlds/test_level.tscn | 121 ++++++++++++++++++++++++++++++ scripts/smoke_test_test_level.gd | 125 +++++++++++++++++++++++++++++++ 2 files changed, 246 insertions(+) create mode 100644 scenes/worlds/test_level.tscn create mode 100644 scripts/smoke_test_test_level.gd diff --git a/scenes/worlds/test_level.tscn b/scenes/worlds/test_level.tscn new file mode 100644 index 0000000..9fe670f --- /dev/null +++ b/scenes/worlds/test_level.tscn @@ -0,0 +1,121 @@ +[gd_scene load_steps=4 format=3 uid="uid://c49a36fc7db_test_level"] + +[ext_resource type="Mesh" path="res://assets/primitives/box_mesh.res" id="1_box"] +[ext_resource type="Mesh" path="res://assets/primitives/cylinder_mesh.res" id="2_cyl"] +[ext_resource type="Mesh" path="res://assets/primitives/sphere_mesh.res" id="3_sphere"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_ground"] +size = Vector3(40, 1, 40) + +[sub_resource type="BoxMesh" id="BoxMesh_ground"] +size = Vector3(40, 1, 40) + +[sub_resource type="BoxShape3D" id="BoxShape3D_prop1"] +size = Vector3(2, 3, 2) + +[sub_resource type="BoxMesh" id="BoxMesh_prop1"] +size = Vector3(2, 3, 2) + +[sub_resource type="BoxShape3D" id="BoxShape3D_prop2"] +size = Vector3(3, 1, 3) + +[sub_resource type="BoxMesh" id="BoxMesh_prop2"] +size = Vector3(3, 1, 3) + +[sub_resource type="CylinderShape3D" id="CylinderShape3D_prop3"] +top_radius = 1.0 +height = 4.0 + +[sub_resource type="CylinderMesh" id="CylinderMesh_prop3"] +top_radius = 1.0 +bottom_radius = 1.0 +height = 4.0 +subdivisions_top_radius = 8 + +[sub_resource type="SphereShape3D" id="SphereShape3D_prop4"] +radius = 1.0 + +[sub_resource type="SphereMesh" id="SphereMesh_prop4"] +radius = 1.0 +subdivisions_ring = 12 +subdivisions_height = 12 + +[sub_resource type="SphereShape3D" id="SphereShape3D_prop5"] +radius = 0.5 + +[sub_resource type="SphereMesh" id="SphereMesh_prop5"] +radius = 0.5 +subdivisions_ring = 8 +subdivisions_height = 8 + +[node name="TestLevel" type="Node3D"] + +[node name="Ground" type="StaticBody3D" parent="."] +position = Vector3(0, -0.5, 0) + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Ground"] +shape = SubResource("BoxShape3D_ground") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Ground"] +mesh = SubResource("BoxMesh_ground") + +[node name="Props" type="Node3D" parent="."] + +[node name="Prop1_Box" type="StaticBody3D" parent="Props"] +position = Vector3(8, 1.5, 8) + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Props/Prop1_Box"] +shape = SubResource("BoxShape3D_prop1") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Props/Prop1_Box"] +mesh = SubResource("BoxMesh_prop1") + +[node name="Prop2_Pedestal" type="StaticBody3D" parent="Props"] +position = Vector3(-8, 0.5, 6) + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Props/Prop2_Pedestal"] +shape = SubResource("BoxShape3D_prop2") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Props/Prop2_Pedestal"] +mesh = SubResource("BoxMesh_prop2") + +[node name="Prop3_Column" type="StaticBody3D" parent="Props"] +position = Vector3(6, 2.0, -8) + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Props/Prop3_Column"] +shape = SubResource("CylinderShape3D_prop3") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Props/Prop3_Column"] +mesh = SubResource("CylinderMesh_prop3") + +[node name="Prop4_Sphere" type="StaticBody3D" parent="Props"] +position = Vector3(-6, 1.0, -6) + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Props/Prop4_Sphere"] +shape = SubResource("SphereShape3D_prop4") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Props/Prop4_Sphere"] +mesh = SubResource("SphereMesh_prop4") + +[node name="Prop5_SmallSphere" type="StaticBody3D" parent="Props"] +position = Vector3(0, 0.5, 12) + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Props/Prop5_SmallSphere"] +shape = SubResource("SphereShape3D_prop5") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Props/Prop5_SmallSphere"] +mesh = SubResource("SphereMesh_prop5") + +[node name="Sun" type="DirectionalLight3D" parent="."] +rotation = Vector3(-0.785398, 0, 0) +shadow_enabled = true + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("WorldEnvironment_env") + +[sub_resource type="Environment" id="WorldEnvironment_env"] +background_mode = 1 +background_color = Color(0.4, 0.6, 0.8, 1) +ambient_light_source = 1 +ambient_light_energy = 0.4 +ambient_light_sky_energy = 1.0 \ No newline at end of file diff --git a/scripts/smoke_test_test_level.gd b/scripts/smoke_test_test_level.gd new file mode 100644 index 0000000..fd7af09 --- /dev/null +++ b/scripts/smoke_test_test_level.gd @@ -0,0 +1,125 @@ +extends SceneTree +## Headless smoke test for the PC2 test level scene. +## +## Run with: +## godot --headless --path . --script res://scripts/smoke_test_test_level.gd +## +## Loads the test level scene, asserts: +## (a) it loads without error, +## (b) it contains a Marker3D named "PlayerSpawn", +## (c) PlayerSpawn is positioned >= 1.0 m above the ground top surface. +## Exits 0 on success, 1 on failure. + + +func _initialize() -> void: + _run() + + +func _run() -> void: + var level_path: String = "res://scenes/worlds/test_level.tscn" + + # Load the scene file + var level_resource: PackedScene = load(level_path) + if level_resource == null: + printerr("SMOKE RESULT: FAIL — could not load ", level_path) + quit(1) + return + + print("SMOKE: test_level.tscn loaded successfully") + + # Instantiate the scene root + var level_instance: Node3D = level_resource.instantiate() as Node3D + if level_instance == null: + printerr("SMOKE RESULT: FAIL — could not instantiate ", level_path) + quit(1) + return + + # Add to tree so find_child works + add_child(level_instance) + await process_frame + + # (b) Find the PlayerSpawn marker + var spawn_marker: Node3D = level_instance.find_child("PlayerSpawn", true, false) as Node3D + if spawn_marker == null: + printerr("SMOKE RESULT: FAIL — no Marker3D named 'PlayerSpawn' found in test level") + level_instance.queue_free() + quit(1) + return + + print("SMOKE: found PlayerSpawn at ", spawn_marker.global_position) + + # (c) Verify PlayerSpawn is >= 1.0 m above ground top + # The ground top surface is at y = 0 (Ground StaticBody3D centered at y = -0.5 + # with height 1.0, so top face is at y = 0). + var spawn_y: float = spawn_marker.global_position.y + if spawn_y < 1.0: + printerr("SMOKE RESULT: FAIL — PlayerSpawn y = ", spawn_y, + " is below the required minimum of 1.0 m above ground top (y=0)") + level_instance.queue_free() + quit(1) + return + + print("SMOKE: PlayerSpawn y = ", spawn_y, " >= 1.0 m — PASS") + + # Additional check: verify Ground StaticBody3D exists + var ground: StaticBody3D = level_instance.find_child("Ground", true, false) as StaticBody3D + if ground == null: + printerr("SMOKE RESULT: FAIL — no StaticBody3D named 'Ground' found") + level_instance.queue_free() + quit(1) + return + + print("SMOKE: found Ground StaticBody3D") + + # Verify Ground top face is at y = 0 + var ground_shape: CollisionShape3D = ground.find_child("CollisionShape3D", true, false) as CollisionShape3D + if ground_shape != null and ground_shape.shape is BoxShape3D: + var box_shape: BoxShape3D = ground_shape.shape as BoxShape3D + var ground_top: float = ground.global_position.y + box_shape.size.y / 2.0 + if abs(ground_top - 0.0) > 0.01: + printerr("SMOKE RESULT: FAIL — Ground top face at y = ", ground_top, " expected ~0.0") + level_instance.queue_free() + quit(1) + return + print("SMOKE: Ground top face at y = ", ground_top, " — PASS") + + # Verify props exist (3-5 StaticBody3D children under Props node) + var props_node: Node3D = level_instance.find_child("Props", true, false) as Node3D + if props_node != null: + var prop_count: int = 0 + for child in props_node.get_children(): + if child is StaticBody3D: + prop_count += 1 + if prop_count < 3: + printerr("SMOKE RESULT: FAIL — only ", prop_count, " props found, need >= 3") + level_instance.queue_free() + quit(1) + return + print("SMOKE: found ", prop_count, " props — PASS") + else: + printerr("SMOKE RESULT: FAIL — no 'Props' Node3D found") + level_instance.queue_free() + quit(1) + return + + # Verify lighting exists + var sun: DirectionalLight3D = level_instance.find_child("Sun", true, false) as DirectionalLight3D + if sun == null: + printerr("SMOKE RESULT: FAIL — no DirectionalLight3D named 'Sun' found") + level_instance.queue_free() + quit(1) + return + print("SMOKE: found Sun DirectionalLight3D") + + var env: WorldEnvironment = level_instance.find_child("Environment", true, false) as WorldEnvironment + if env == null: + printerr("SMOKE RESULT: FAIL — no WorldEnvironment named 'Environment' found") + level_instance.queue_free() + quit(1) + return + print("SMOKE: found WorldEnvironment") + + # All checks passed + print("SMOKE RESULT: PASS") + level_instance.queue_free() + quit(0) -- 2.52.0 From 6648b2bba59be7c5b62bf93480b361f80934070d Mon Sep 17 00:00:00 2001 From: coder-bot Date: Thu, 20 Aug 2026 22:31:46 +0000 Subject: [PATCH 2/5] WIP checkpoint: PC2: Build a basic playable test level scene --- scripts/smoke_test_test_level.gd | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/scripts/smoke_test_test_level.gd b/scripts/smoke_test_test_level.gd index fd7af09..2a87eb9 100644 --- a/scripts/smoke_test_test_level.gd +++ b/scripts/smoke_test_test_level.gd @@ -34,8 +34,10 @@ func _run() -> void: quit(1) return - # Add to tree so find_child works - add_child(level_instance) + # Create a temporary root node and add it to the tree so find_child works + var root_holder := Node3D.new() + add_child(root_holder) + root_holder.add_child(level_instance) await process_frame # (b) Find the PlayerSpawn marker @@ -43,6 +45,7 @@ func _run() -> void: if spawn_marker == null: printerr("SMOKE RESULT: FAIL — no Marker3D named 'PlayerSpawn' found in test level") level_instance.queue_free() + root_holder.queue_free() quit(1) return @@ -56,6 +59,7 @@ func _run() -> void: printerr("SMOKE RESULT: FAIL — PlayerSpawn y = ", spawn_y, " is below the required minimum of 1.0 m above ground top (y=0)") level_instance.queue_free() + root_holder.queue_free() quit(1) return @@ -66,6 +70,7 @@ func _run() -> void: if ground == null: printerr("SMOKE RESULT: FAIL — no StaticBody3D named 'Ground' found") level_instance.queue_free() + root_holder.queue_free() quit(1) return @@ -79,6 +84,7 @@ func _run() -> void: if abs(ground_top - 0.0) > 0.01: printerr("SMOKE RESULT: FAIL — Ground top face at y = ", ground_top, " expected ~0.0") level_instance.queue_free() + root_holder.queue_free() quit(1) return print("SMOKE: Ground top face at y = ", ground_top, " — PASS") @@ -93,12 +99,14 @@ func _run() -> void: if prop_count < 3: printerr("SMOKE RESULT: FAIL — only ", prop_count, " props found, need >= 3") level_instance.queue_free() + root_holder.queue_free() quit(1) return print("SMOKE: found ", prop_count, " props — PASS") else: printerr("SMOKE RESULT: FAIL — no 'Props' Node3D found") level_instance.queue_free() + root_holder.queue_free() quit(1) return @@ -107,6 +115,7 @@ func _run() -> void: if sun == null: printerr("SMOKE RESULT: FAIL — no DirectionalLight3D named 'Sun' found") level_instance.queue_free() + root_holder.queue_free() quit(1) return print("SMOKE: found Sun DirectionalLight3D") @@ -115,6 +124,7 @@ func _run() -> void: if env == null: printerr("SMOKE RESULT: FAIL — no WorldEnvironment named 'Environment' found") level_instance.queue_free() + root_holder.queue_free() quit(1) return print("SMOKE: found WorldEnvironment") @@ -122,4 +132,5 @@ func _run() -> void: # All checks passed print("SMOKE RESULT: PASS") level_instance.queue_free() + root_holder.queue_free() quit(0) -- 2.52.0 From 3f7acf857c2b52f4ae04a8c33c39cc3b26ae2008 Mon Sep 17 00:00:00 2001 From: coder-bot Date: Thu, 20 Aug 2026 22:41:53 +0000 Subject: [PATCH 3/5] WIP checkpoint: PC2: Build a basic playable test level scene --- scripts/smoke_test_test_level.gd | 42 ++++++++++++-------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/scripts/smoke_test_test_level.gd b/scripts/smoke_test_test_level.gd index 2a87eb9..7e92d71 100644 --- a/scripts/smoke_test_test_level.gd +++ b/scripts/smoke_test_test_level.gd @@ -27,25 +27,29 @@ func _run() -> void: print("SMOKE: test_level.tscn loaded successfully") - # Instantiate the scene root - var level_instance: Node3D = level_resource.instantiate() as Node3D - if level_instance == null: - printerr("SMOKE RESULT: FAIL — could not instantiate ", level_path) + # Change the running scene to our test level + var err: int = change_scene_to_packed(level_resource) + if err != OK: + printerr("SMOKE RESULT: FAIL — change_scene_to_packed returned ", err) quit(1) return - # Create a temporary root node and add it to the tree so find_child works - var root_holder := Node3D.new() - add_child(root_holder) - root_holder.add_child(level_instance) + # Wait for the scene_changed signal so current_scene is set + await scene_changed + + var level_instance: Node3D = current_scene as Node3D + if level_instance == null: + printerr("SMOKE RESULT: FAIL — current_scene is not Node3D") + quit(1) + return + + # Give the tree one frame to fully initialize await process_frame # (b) Find the PlayerSpawn marker var spawn_marker: Node3D = level_instance.find_child("PlayerSpawn", true, false) as Node3D if spawn_marker == null: - printerr("SMOKE RESULT: FAIL — no Marker3D named 'PlayerSpawn' found in test level") - level_instance.queue_free() - root_holder.queue_free() + printerr("SMOKE RESULT: FAIL — no Node3D named 'PlayerSpawn' found in test level") quit(1) return @@ -58,8 +62,6 @@ func _run() -> void: if spawn_y < 1.0: printerr("SMOKE RESULT: FAIL — PlayerSpawn y = ", spawn_y, " is below the required minimum of 1.0 m above ground top (y=0)") - level_instance.queue_free() - root_holder.queue_free() quit(1) return @@ -69,8 +71,6 @@ func _run() -> void: var ground: StaticBody3D = level_instance.find_child("Ground", true, false) as StaticBody3D if ground == null: printerr("SMOKE RESULT: FAIL — no StaticBody3D named 'Ground' found") - level_instance.queue_free() - root_holder.queue_free() quit(1) return @@ -83,8 +83,6 @@ func _run() -> void: var ground_top: float = ground.global_position.y + box_shape.size.y / 2.0 if abs(ground_top - 0.0) > 0.01: printerr("SMOKE RESULT: FAIL — Ground top face at y = ", ground_top, " expected ~0.0") - level_instance.queue_free() - root_holder.queue_free() quit(1) return print("SMOKE: Ground top face at y = ", ground_top, " — PASS") @@ -98,15 +96,11 @@ func _run() -> void: prop_count += 1 if prop_count < 3: printerr("SMOKE RESULT: FAIL — only ", prop_count, " props found, need >= 3") - level_instance.queue_free() - root_holder.queue_free() quit(1) return print("SMOKE: found ", prop_count, " props — PASS") else: printerr("SMOKE RESULT: FAIL — no 'Props' Node3D found") - level_instance.queue_free() - root_holder.queue_free() quit(1) return @@ -114,8 +108,6 @@ func _run() -> void: var sun: DirectionalLight3D = level_instance.find_child("Sun", true, false) as DirectionalLight3D if sun == null: printerr("SMOKE RESULT: FAIL — no DirectionalLight3D named 'Sun' found") - level_instance.queue_free() - root_holder.queue_free() quit(1) return print("SMOKE: found Sun DirectionalLight3D") @@ -123,14 +115,10 @@ func _run() -> void: var env: WorldEnvironment = level_instance.find_child("Environment", true, false) as WorldEnvironment if env == null: printerr("SMOKE RESULT: FAIL — no WorldEnvironment named 'Environment' found") - level_instance.queue_free() - root_holder.queue_free() quit(1) return print("SMOKE: found WorldEnvironment") # All checks passed print("SMOKE RESULT: PASS") - level_instance.queue_free() - root_holder.queue_free() quit(0) -- 2.52.0 From fdc43bd5f12d2b1ea9d556da7b9faa8e2aa1969a Mon Sep 17 00:00:00 2001 From: coder-bot Date: Thu, 20 Aug 2026 23:01:55 +0000 Subject: [PATCH 4/5] WIP checkpoint: PC2: Build a basic playable test level scene --- scenes/worlds/test_level.tscn | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/scenes/worlds/test_level.tscn b/scenes/worlds/test_level.tscn index 9fe670f..21b4354 100644 --- a/scenes/worlds/test_level.tscn +++ b/scenes/worlds/test_level.tscn @@ -1,8 +1,4 @@ -[gd_scene load_steps=4 format=3 uid="uid://c49a36fc7db_test_level"] - -[ext_resource type="Mesh" path="res://assets/primitives/box_mesh.res" id="1_box"] -[ext_resource type="Mesh" path="res://assets/primitives/cylinder_mesh.res" id="2_cyl"] -[ext_resource type="Mesh" path="res://assets/primitives/sphere_mesh.res" id="3_sphere"] +[gd_scene load_steps=1 format=3 uid="uid://c49a36fc7db_test_level"] [sub_resource type="BoxShape3D" id="BoxShape3D_ground"] size = Vector3(40, 1, 40) @@ -48,6 +44,13 @@ radius = 0.5 subdivisions_ring = 8 subdivisions_height = 8 +[sub_resource type="Environment" id="WorldEnvironment_env"] +background_mode = 1 +background_color = Color(0.4, 0.6, 0.8, 1) +ambient_light_source = 1 +ambient_light_energy = 0.4 +ambient_light_sky_energy = 1.0 + [node name="TestLevel" type="Node3D"] [node name="Ground" type="StaticBody3D" parent="."] @@ -113,9 +116,5 @@ shadow_enabled = true [node name="WorldEnvironment" type="WorldEnvironment" parent="."] environment = SubResource("WorldEnvironment_env") -[sub_resource type="Environment" id="WorldEnvironment_env"] -background_mode = 1 -background_color = Color(0.4, 0.6, 0.8, 1) -ambient_light_source = 1 -ambient_light_energy = 0.4 -ambient_light_sky_energy = 1.0 \ No newline at end of file +[node name="PlayerSpawn" type="Marker3D" parent="."] +position = Vector3(0, 1.5, 0) -- 2.52.0 From e33b91d976a194fcc39f3b887fdf83c74f7ec5a5 Mon Sep 17 00:00:00 2001 From: coder-bot Date: Thu, 20 Aug 2026 23:17:43 +0000 Subject: [PATCH 5/5] WIP checkpoint: PC2: Build a basic playable test level scene --- scripts/smoke_test_test_level.gd | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/scripts/smoke_test_test_level.gd b/scripts/smoke_test_test_level.gd index 7e92d71..655db3a 100644 --- a/scripts/smoke_test_test_level.gd +++ b/scripts/smoke_test_test_level.gd @@ -21,7 +21,7 @@ func _run() -> void: # Load the scene file var level_resource: PackedScene = load(level_path) if level_resource == null: - printerr("SMOKE RESULT: FAIL — could not load ", level_path) + printerr("SMOKE RESULT: FAIL \u2014 could not load ", level_path) quit(1) return @@ -30,7 +30,7 @@ func _run() -> void: # Change the running scene to our test level var err: int = change_scene_to_packed(level_resource) if err != OK: - printerr("SMOKE RESULT: FAIL — change_scene_to_packed returned ", err) + printerr("SMOKE RESULT: FAIL \u2014 change_scene_to_packed returned ", err) quit(1) return @@ -39,7 +39,7 @@ func _run() -> void: var level_instance: Node3D = current_scene as Node3D if level_instance == null: - printerr("SMOKE RESULT: FAIL — current_scene is not Node3D") + printerr("SMOKE RESULT: FAIL \u2014 current_scene is not Node3D") quit(1) return @@ -49,7 +49,7 @@ func _run() -> void: # (b) Find the PlayerSpawn marker var spawn_marker: Node3D = level_instance.find_child("PlayerSpawn", true, false) as Node3D if spawn_marker == null: - printerr("SMOKE RESULT: FAIL — no Node3D named 'PlayerSpawn' found in test level") + printerr("SMOKE RESULT: FAIL \u2014 no Node3D named 'PlayerSpawn' found in test level") quit(1) return @@ -60,17 +60,17 @@ func _run() -> void: # with height 1.0, so top face is at y = 0). var spawn_y: float = spawn_marker.global_position.y if spawn_y < 1.0: - printerr("SMOKE RESULT: FAIL — PlayerSpawn y = ", spawn_y, + printerr("SMOKE RESULT: FAIL \u2014 PlayerSpawn y = ", spawn_y, " is below the required minimum of 1.0 m above ground top (y=0)") quit(1) return - print("SMOKE: PlayerSpawn y = ", spawn_y, " >= 1.0 m — PASS") + print("SMOKE: PlayerSpawn y = ", spawn_y, " >= 1.0 m \u2014 PASS") # Additional check: verify Ground StaticBody3D exists var ground: StaticBody3D = level_instance.find_child("Ground", true, false) as StaticBody3D if ground == null: - printerr("SMOKE RESULT: FAIL — no StaticBody3D named 'Ground' found") + printerr("SMOKE RESULT: FAIL \u2014 no StaticBody3D named 'Ground' found") quit(1) return @@ -82,10 +82,10 @@ func _run() -> void: var box_shape: BoxShape3D = ground_shape.shape as BoxShape3D var ground_top: float = ground.global_position.y + box_shape.size.y / 2.0 if abs(ground_top - 0.0) > 0.01: - printerr("SMOKE RESULT: FAIL — Ground top face at y = ", ground_top, " expected ~0.0") + printerr("SMOKE RESULT: FAIL \u2014 Ground top face at y = ", ground_top, " expected ~0.0") quit(1) return - print("SMOKE: Ground top face at y = ", ground_top, " — PASS") + print("SMOKE: Ground top face at y = ", ground_top, " \u2014 PASS") # Verify props exist (3-5 StaticBody3D children under Props node) var props_node: Node3D = level_instance.find_child("Props", true, false) as Node3D @@ -95,26 +95,27 @@ func _run() -> void: if child is StaticBody3D: prop_count += 1 if prop_count < 3: - printerr("SMOKE RESULT: FAIL — only ", prop_count, " props found, need >= 3") + printerr("SMOKE RESULT: FAIL \u2014 only ", prop_count, " props found, need >= 3") quit(1) return - print("SMOKE: found ", prop_count, " props — PASS") + print("SMOKE: found ", prop_count, " props \u2014 PASS") else: - printerr("SMOKE RESULT: FAIL — no 'Props' Node3D found") + printerr("SMOKE RESULT: FAIL \u2014 no 'Props' Node3D found") quit(1) return # Verify lighting exists var sun: DirectionalLight3D = level_instance.find_child("Sun", true, false) as DirectionalLight3D if sun == null: - printerr("SMOKE RESULT: FAIL — no DirectionalLight3D named 'Sun' found") + printerr("SMOKE RESULT: FAIL \u2014 no DirectionalLight3D named 'Sun' found") quit(1) return print("SMOKE: found Sun DirectionalLight3D") - var env: WorldEnvironment = level_instance.find_child("Environment", true, false) as WorldEnvironment + # Verify WorldEnvironment exists + var env: WorldEnvironment = level_instance.find_child("WorldEnvironment", true, false) as WorldEnvironment if env == null: - printerr("SMOKE RESULT: FAIL — no WorldEnvironment named 'Environment' found") + printerr("SMOKE RESULT: FAIL \u2014 no WorldEnvironment named 'WorldEnvironment' found") quit(1) return print("SMOKE: found WorldEnvironment") -- 2.52.0