extends SceneTree var failed := 0 var total := 0 func _initialize() -> void: call_deferred("run") func check(ok: bool, title: String) -> void: total += 1 if not ok: failed += 1 print("PASS " if ok else "FAIL ", title) func run() -> void: var game: Node3D = load("res://scenes/main.tscn").instantiate() root.add_child(game) game.port = 27986 game.host({"server_name":"Foundation", "mode":"FFA", "max_players":2, "bots":0, "score_limit":100, "time_limit":600}) game.set_physics_process(false) var p: Fighter = game.players[1] p.set_physics_process(false) p.set_process(false) p.reset_at(Vector3(0, 0.1, 28)) check(p.shape.shape is CapsuleShape3D and p.find_children("*", "CollisionShape3D", true, false).size() == 1, "fighter exclusively uses one capsule") var scans: Node = game.arena.get_node("QuarryRouteRocks") var bodies: Array[Node] = scans.find_children("*", "StaticBody3D", true, false) check(bodies.size() == 2, "two scan mesh colliders restored on headless host") var boxes := true for body in bodies: boxes = boxes and body.get_child(0).shape is ConcavePolygonShape3D check(boxes, "route scans use original triangle collision") var motion := InputEventMouseMotion.new() motion.screen_relative = Vector2(20, -10) motion.relative = Vector2(999,999) FpsCamera.mouse(p, motion, 0.001) check(is_equal_approx(p.yaw, -0.02) and is_equal_approx(p.pitch, 0.01), "raw screen-relative mouse input applied without smoothing") p.view_controller.begin_physics(p) var body_position := p.global_position for rate in [60, 120, 144, 240]: p.view_controller.render(p, 1.0 / rate) check(p.global_position == body_position and is_equal_approx(p.camera.global_rotation.y, p.yaw), "camera render preserves physics and direct yaw at %s Hz" % rate) game.headless = false game.hud.hit_time = 0 game.shot_event(p.eye(), p.peer_id, p.weapon, false, false) check(p.gun.muzzle.visible and p.gun.recoil_velocity.length() > 0 and game.hud.shot_time > 0, "single shot event immediately starts flash, recoil and crosshair pulse") check(game.hud.hit_time == 0, "miss does not fake a hitmarker") var recoil_before: Vector2 = p.gun.recoil_velocity p.magazines[p.weapon] -= 1 p.shot_serial += 1 p.gun.animate(p, 0.0) check(p.gun.recoil_velocity.is_equal_approx(recoil_before), "snapshot ammo change does not duplicate recoil") game.shot_event(p.eye(), p.peer_id, p.weapon, true, true) check(game.hud.hit_time > 0 and game.hud.head_hit, "confirmed headshot adds hit feedback in same event") for index in 10: p.weapon = index p.skin_designs[str(index)] = {"attachments": {"optic":1}} p.gun.select_weapon(index) p.gun.previous_life = p.life WeaponSkins.apply(p.gun.model, p.skin_designs[str(index)]) p.aim_blend = 1 p.gun.position = Vector3(0.18,-0.22,-0.43) p.gun.animate(p, 0.016) var lens: Node3D = p.gun.model.get_node("Bolt/SlideAttachments/Reflex/Lens" if index == 4 else "Attachments/Reflex/Lens") var center := p.camera.to_local(lens.global_position) check(Vector2(center.x, center.y).length() < 0.0001, "reflex center on optical axis weapon %s" % index) var guard_root := Node3D.new() root.add_child(guard_root) StairGuard.build(guard_root, 0, 0, 1, 0, 3.7) var guard: StaticBody3D = guard_root.get_child(0) check(guard.get_child_count() == 1 and guard.get_child(0).shape is ConvexPolygonShape3D, "guard is one continuous convex slope") var walker := CharacterBody3D.new() var capsule_shape := CollisionShape3D.new() var capsule := CapsuleShape3D.new() capsule.radius = 0.36 capsule.height = 1.8 capsule_shape.shape = capsule walker.add_child(capsule_shape) guard_root.add_child(walker) await physics_frame await physics_frame var smooth := true for step in 70: var z := step * 0.1 walker.position = Vector3(0.425, 0.95 + z * 3.7 / 7.6, z) smooth = smooth and not walker.test_move(walker.global_transform, Vector3(0, 0.1 * 3.7 / 7.6, 0.1)) check(smooth, "capsule sweeps along guard without catching seams") guard_root.queue_free() game.leave() game.queue_free() await process_frame print("CORRECTIONS RESULT ", total - failed, "/", total) quit(1 if failed else 0)