extends SceneTree ## Runtime release gate for the premium audio pass. ## ## Uses a real Forward+ match so it verifies autoload ordering, imported audio ## resources, a spawned player's movement players, and a live weapon loadout. var _frames := 0 var _phase := "menu" var _failures: Array[String] = [] const REQUIRED_EVENTS := [ "ak47_fire", "m4_fire", "mp7_fire", "dmr_fire", "awp_fire", "shotgun_fire", "nailgun_fire", "plasma_fire", "rocket_fire", "swarm_fire", "mortar_fire", "knife_swing", "shotgun_reload", "explosion", "bullet_impact", "footstep_concrete", "footstep_metal", "footstep_wood", "footstep_glass", "wind", "slide", "wallrun", "dash", "jump", "double_jump", "vault", "land", "grapple_launch", "grapple_latch", "grapple_reel", "ui_hover", "ui_click", "ui_confirm", "ui_error", "ui_equip", ] func _initialize() -> void: change_scene_to_file("res://ui/main_menu/main_menu.tscn") func _process(_delta: float) -> bool: _frames += 1 if _phase == "menu" and _frames == 50: _verify_menu_music() _verify_manager() var network = root.get_node_or_null("NetworkManager") if network and network.has_method("start_singleplayer_match"): network.start_singleplayer_match(GameMode.DEATHMATCH) else: _fail("NetworkManager cannot start the runtime audio match") change_scene_to_file("res://scenes/maps/test_level/test_level.tscn") _phase = "match" _frames = 0 elif _phase == "match" and _frames == 180: _verify_live_player() _phase = "drain" _frames = 0 unload_current_scene() elif _phase == "drain" and _frames >= 90: _finish() return false func _verify_menu_music() -> void: var found := false if current_scene: for candidate in current_scene.find_children("*", "AudioStreamPlayer", true, false): var player := candidate as AudioStreamPlayer if player.bus == "Music": found = true _check(player.playing, "menu music is playing") _check(player.stream is AudioStreamOggVorbis, "menu music is an imported Ogg stream") if player.stream is AudioStreamOggVorbis: _check((player.stream as AudioStreamOggVorbis).loop, "menu music loops") break _check(found, "main menu owns a Music-bus player") func _verify_manager() -> void: var am = root.get_node_or_null("AudioManager") _check(am != null, "AudioManager autoload exists") if am == null: return for event in REQUIRED_EVENTS: _check(am.has_sound(event), "event resolves: %s" % event) _check(am.weapon_sound_id("Double Barrel") == "shotgun_fire", "multiplayer shotgun broadcast resolves to its fire family") var expected_sends := { "SFX": "Master", "Weapons": "SFX", "Explosions": "SFX", "Impacts": "SFX", "Footsteps": "SFX", "Movement": "SFX", "Ambience": "SFX", "UI": "SFX", "Wind": "SFX", "Music": "Master", } for bus_name in expected_sends: var bus := AudioServer.get_bus_index(bus_name) _check(bus >= 0, "bus exists: %s" % bus_name) if bus >= 0: _check(AudioServer.get_bus_send(bus) == expected_sends[bus_name], "%s routes to %s" % [bus_name, expected_sends[bus_name]]) var master := AudioServer.get_bus_index("Master") _check(_bus_has_effect(master, "AudioEffectHardLimiter"), "Master has a hard limiter") _check(_bus_has_effect(AudioServer.get_bus_index("Weapons"), "AudioEffectCompressor"), "Weapons has transient compression") _check(_bus_has_effect(AudioServer.get_bus_index("Explosions"), "AudioEffectCompressor"), "Explosions has body compression") var loop_stream: AudioStream = am.stream_for("wind") _check(loop_stream is AudioStreamRandomizer, "wind resolves through variation stream") if loop_stream is AudioStreamRandomizer: var randomizer := loop_stream as AudioStreamRandomizer _check(randomizer.streams_count >= 1, "wind has a source stream") var child := randomizer.get_stream(0) _check(child is AudioStreamWAV, "wind source is WAV") if child is AudioStreamWAV: var wav := child as AudioStreamWAV _check(wav.loop_mode == AudioStreamWAV.LOOP_FORWARD, "wind source has forward looping enabled") _check(wav.loop_end > 0, "wind source has an explicit loop end") var first = am.play_ui("ui_hover") var suppressed = am.play_ui("ui_hover") _check(first != null, "UI hover plays") _check(suppressed == null, "UI hover chatter is rate-limited") var click = am.play_ui("ui_click") _check(click != null and click.bus == "UI", "UI click plays on the UI bus") var explosion = am.play_3d("explosion", Vector3.ZERO) _check(explosion != null and explosion.bus == "Explosions", "explosion plays on the Explosions bus") for material in ["concrete", "metal", "wood", "glass"]: var surface := Node.new() surface.set_meta("acoustic_material", material) _check(Acoustics.classify(surface) == material, "surface classifier preserves %s" % material) surface.free() func _verify_live_player() -> void: var ambience := current_scene.get_node_or_null("AmbientBed") \ if current_scene else null _check(ambience == null, "level has no always-on broadband ambience") var player = null for candidate in root.find_children("*", "CharacterBody3D", true, false): if candidate.has_method("get_visual_model") \ and candidate.is_multiplayer_authority(): player = candidate break _check(player != null, "single-player match spawned the local player") if player == null: return _check(player.has_method("surface_event"), "player exposes material event lookup") var foot_event: String = player.surface_event("footstep") _check(foot_event in [ "footstep_concrete", "footstep_metal", "footstep_wood", "footstep_glass"], "live floor resolves to a footstep family (%s)" % foot_event) player.play_footstep(8.0) _check(player.footstep_player.bus == "Footsteps", "local footsteps use the Footsteps bus") _check(player.footstep_player.playing, "local material footstep plays") player.update_slide_audio(14.0) _check(player.slide_player.bus == "Movement", "slide uses the Movement bus") _check(player.slide_player.stream is AudioStreamRandomizer, "slide uses the mastered looping family") player.update_wallrun_audio(14.0, Vector3.LEFT) _check(player.wallrun_player.bus == "Movement", "wall-run uses the Movement bus") _check(player.wind_player.bus == "Wind", "speed wind uses the independent Wind bus") _check(player.grapple_shoot_player.bus == "Movement", "grapple launch uses the Movement bus") _check(player.grapple_latch_player.bus == "Movement", "grapple latch uses the Movement bus") _check(player.grapple_swing_player.bus == "Movement", "grapple reel uses the Movement bus") _check(player.jump_player.stream != player.double_jump_player.stream, "ground jump and powered double jump use distinct masters") var grapple_streams := [ player.grapple_shoot_player.stream, player.grapple_latch_player.stream, player.grapple_swing_player.stream, ] _check(grapple_streams[0] != grapple_streams[1] and grapple_streams[0] != grapple_streams[2] and grapple_streams[1] != grapple_streams[2], "grapple launch, latch and reel use three distinct masters") _check(player.jump_player.stream not in grapple_streams and player.double_jump_player.stream not in grapple_streams and player.dash_player.stream not in grapple_streams, "grapple stages do not reuse jump or jet-thrust masters") _check(_randomizer_has_loop(player.grapple_swing_player.stream), "grapple reel resolves to an explicitly looping cable stream") player._on_movement_event("grapple_shoot", {}) _check(player.grapple_shoot_player.playing, "grapple shoot event plays the cable launcher") player._on_movement_event("grapple_latch", {}) _check(player.grapple_latch_player.playing, "grapple latch event plays the hook impact") _check(player._jet_vfx != null and player._jet_vfx.get_flame_count() == 4, "live player owns exactly four jet flames") var jet_before: float = player._jet_vfx._burst_left player._on_movement_event("jump", {}) _check(is_equal_approx(player._jet_vfx._burst_left, jet_before), "ordinary jump does not ignite the jets") player._on_movement_event("double_jump", {}) _check(player._jet_vfx._burst_left > 0.0, "double jump ignites the four-jet burst") var managers: Array[Node] = player.find_children( "WeaponManager", "WeaponManager", true, false) _check(not managers.is_empty(), "live player has a WeaponManager") if not managers.is_empty(): var manager = managers[0] var checked_weapons := 0 for weapon in manager.weapons.values(): if weapon and "fire_sound" in weapon and weapon.fire_sound: checked_weapons += 1 _check(weapon.fire_sound.bus == "Weapons", "%s fire routes to Weapons" % weapon.weapon_name) _check(weapon.fire_sound.stream is AudioStreamRandomizer, "%s uses the mastered variation family" % weapon.weapon_name) _check(weapon.fire_sound.max_polyphony >= 4, "%s shots keep overlapping body/tails" % weapon.weapon_name) _check(checked_weapons >= 3, "at least three live weapon players verified") func _randomizer_has_loop(stream: AudioStream) -> bool: if not stream is AudioStreamRandomizer: return false var randomizer := stream as AudioStreamRandomizer if randomizer.streams_count < 1: return false var child := randomizer.get_stream(0) return child is AudioStreamWAV \ and (child as AudioStreamWAV).loop_mode == AudioStreamWAV.LOOP_FORWARD func _bus_has_effect(bus: int, effect_class: String) -> bool: if bus < 0: return false for i in AudioServer.get_bus_effect_count(bus): var effect := AudioServer.get_bus_effect(bus, i) if effect and effect.is_class(effect_class): return true return false func _check(condition: bool, label: String) -> void: if condition: print(" PASS: ", label) else: _fail(label) func _fail(label: String) -> void: _failures.append(label) printerr("AUDIO_FIDELITY FAIL: ", label) func _finish() -> void: if _failures.is_empty(): print("AUDIO_FIDELITY PASSED") quit(0) else: printerr("AUDIO_FIDELITY failures=", _failures.size()) quit(1)