extends SceneTree var failures := 0 var checks := 0 func _initialize() -> void: call_deferred("run") func check(ok: bool, message: String) -> void: checks += 1 if not ok: failures += 1 print("PASS " if ok else "FAIL ", message) func run() -> void: var audio := ArenaAudio.new() root.add_child(audio) for local in [true,false]: for i in 8: audio.play_shot("shot_0", Vector3.ZERO, local) check(audio.shot_players.size() == 2, "shot players reused rather than allocated per shot") for player in audio.shot_players.values(): check(player.max_polyphony == 3 and player.pitch_scale >= 0.95 and player.pitch_scale <= 1.05, "polyphony and pitch limits") var limited := false for i in AudioServer.get_bus_effect_count(0): limited = limited or AudioServer.get_bus_effect(0,i) is AudioEffectLimiter check(limited, "master limiter installed") for profile in WeaponHandling.DATA: var states := [] for rate in [60,240]: var state: Array[Vector2] = [Vector2.ZERO, Vector2(profile.kick,profile.rise)*profile.spring*2.1] for tick in rate: state = WeaponHandling.settle(state[0],state[1],profile.spring,1.0/rate) states.append(state) check(states[0][0].distance_to(states[1][0]) < 0.00001, "recoil trajectory endpoint matches at 60/240 Hz") var stop := HitStop.new() root.add_child(stop) var started := Time.get_ticks_usec() stop.trigger() check(Engine.time_scale == 0.05, "hit-stop applies five percent") while stop.running: await process_frame var elapsed := (Time.get_ticks_usec()-started)/1000.0 check(Engine.time_scale == 1.0 and elapsed >= 29 and elapsed < 100, "hit-stop restores on real-time deadline; ms="+str(elapsed)) stop.trigger() stop.restore() check(Engine.time_scale == 1.0, "leaving restores time immediately") await create_timer(0.5, true, false, true).timeout var stage := Node3D.new() root.add_child(stage) var fighter := Fighter.new() fighter.add_child(fighter.movement) fighter.add_child(fighter.weapon_controller) fighter.add_child(fighter.replication_state) fighter.set_process(false) fighter.set_physics_process(false) stage.add_child(fighter) fighter.process_mode = Node.PROCESS_MODE_DISABLED var target := StaticBody3D.new() target.position = Vector3(0,0,-5) var box := BoxShape3D.new() var collider := CollisionShape3D.new() collider.shape = box target.add_child(collider) stage.add_child(target) await physics_frame await physics_frame var hit := HitscanRay.cast(fighter, Vector3.ZERO, Vector3(0,0,-10), 1) check(hit.get("collider") == target and fighter.get_node("HitscanRay") is RayCast3D, "RayCast3D hits world cover immediately") check(HitscanRay.cast(fighter, Vector3.ZERO, Vector3(0,5,-10), 1).is_empty(), "RayCast3D clears previous hit on miss") stage.queue_free() audio.queue_free() stop.queue_free() await process_frame print("POLISH RESULT ", checks-failures,"/",checks) quit(1 if failures else 0)