From 2102affb09d07117201ab22dc144ec8d2b2fc4e8 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Fri, 16 Oct 2026 17:18:11 +0200 Subject: [PATCH] Audio 1: the simulation names no sound; delete the dead Wwise path on EquippedItem Removes EquippedItem's SoundBank, AudioEvents/AudioParameters, every FireAudioEvent/PlaySound/StopSound/SetAudioParameter overload and Update's AudioStats loop, the four audio enums, WwiseMetadata and WwiseSoundBinding, the weapon/reactor/thruster call sites, and the Wwise Sounds counters in FireControlPerWeaponTests (Announced and Starts keep the refused-round pins). Catalog keys 21, 22 and 13-15 stay, unread. Builds. Co-Authored-By: Claude Opus 5.5 --- .../ServerShared/Behaviors/ChargedWeapon.cs | 4 - .../ServerShared/Behaviors/InstantWeapon.cs | 6 -- .../Scripts/ServerShared/Behaviors/Reactor.cs | 2 - .../ServerShared/Behaviors/Thruster.cs | 1 - Assets/Scripts/ServerShared/Entity.cs | 81 ---------------- Assets/Scripts/ServerShared/Enums.cs | 28 ------ Assets/Scripts/ServerShared/WwiseMetadata.cs | 92 ------------------- .../ServerShared/WwiseMetadata.cs.meta | 3 - .../Scripts/ServerShared/WwiseSoundBinding.cs | 22 ----- .../ServerShared/WwiseSoundBinding.cs.meta | 3 - .../FireControlPerWeaponTests.cs | 24 ++--- 11 files changed, 7 insertions(+), 259 deletions(-) delete mode 100644 Assets/Scripts/ServerShared/WwiseMetadata.cs delete mode 100644 Assets/Scripts/ServerShared/WwiseMetadata.cs.meta delete mode 100644 Assets/Scripts/ServerShared/WwiseSoundBinding.cs delete mode 100644 Assets/Scripts/ServerShared/WwiseSoundBinding.cs.meta diff --git a/Assets/Scripts/ServerShared/Behaviors/ChargedWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/ChargedWeapon.cs index 3f753e7f4..8d048083d 100644 --- a/Assets/Scripts/ServerShared/Behaviors/ChargedWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/ChargedWeapon.cs @@ -145,7 +145,6 @@ public class ChargedWeapon : InstantWeapon if (_charging) { _charge += dt / ChargeTime; - Item.SetAudioParameter(SpecialAudioParameter.ChargeLevel, saturate(_charge)); if (!_charged) { AddHeat(ChargeHeat * (dt / ChargeTime)); @@ -162,7 +161,6 @@ public class ChargedWeapon : InstantWeapon _coolingDown = true; _charge = 0; OnFailed?.Invoke(); - Item.FireAudioEvent(ChargedWeaponAudioEvent.Fail); CauseDamage(_data.FailureDamage); } } @@ -177,7 +175,6 @@ public class ChargedWeapon : InstantWeapon if(!_charging && CanFire && !FireControl.Refuses(this, Entity)) { OnStartCharging?.Invoke(); - Item.FireAudioEvent(ChargedWeaponAudioEvent.Start); _charging = true; _charged = false; } @@ -193,7 +190,6 @@ public class ChargedWeapon : InstantWeapon _charge = 0; } OnStopCharging?.Invoke(); - Item.FireAudioEvent(ChargedWeaponAudioEvent.Stop); _charging = false; } } diff --git a/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs index 0382c3b17..043df920c 100644 --- a/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs @@ -240,7 +240,6 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior, IPowerCo } } - var firedThisFrame = false; _burstTimer += dt; while (_burstRemaining > 0 && _burstTimer > 0) { @@ -280,11 +279,6 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior, IPowerCo // Evaluate it into a local first. var shotId = FireControl.Fire(this, Item, Entity); OnFire?.Invoke(shotId); - if(!firedThisFrame) - { - Item.FireAudioEvent(WeaponAudioEvent.Fire); - firedThisFrame = true; - } CauseWearDamage(1); AddHeat(Heat); Entity.SetSignature(this, SignatureChannel.LaunchFlash, Visibility, Item); diff --git a/Assets/Scripts/ServerShared/Behaviors/Reactor.cs b/Assets/Scripts/ServerShared/Behaviors/Reactor.cs index e5321ac17..14cc1424c 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Reactor.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Reactor.cs @@ -94,8 +94,6 @@ public class Reactor : Behavior Draw = 0; } - Item.SetAudioParameter(SpecialAudioParameter.Intensity, max(.25f, 1 - 1 / CurrentLoadRatio)); - AddHeat(heat); return true; } diff --git a/Assets/Scripts/ServerShared/Behaviors/Thruster.cs b/Assets/Scripts/ServerShared/Behaviors/Thruster.cs index b15378cea..a349ad744 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Thruster.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Thruster.cs @@ -109,7 +109,6 @@ public class Thruster : Behavior, IPowerConsumer public override bool Execute(float dt) { - Item.SetAudioParameter(SpecialAudioParameter.Intensity, _input); // Cut 7 (docs/stats-and-power-target.md): "continuous consumers brown out ... through a power supply // curve on their performance stats." Thrust below is a plain Evaluate() read, so once the catalog's own // Thrust stat carries a PowerSupply term, a partial grant already comes back reduced -- this gate no diff --git a/Assets/Scripts/ServerShared/Entity.cs b/Assets/Scripts/ServerShared/Entity.cs index 4d9470963..9722297d5 100644 --- a/Assets/Scripts/ServerShared/Entity.cs +++ b/Assets/Scripts/ServerShared/Entity.cs @@ -2149,7 +2149,6 @@ public class EquippedItem : IStatContext private bool _thermalOnline; private bool _durabilityOnline; - public WwiseMetaSoundBank SoundBank; public Behavior[] Behaviors { get; } public Dictionary BehaviorGroups { get; } @@ -2175,10 +2174,6 @@ public class EquippedItem : IStatContext public ReadOnlyReactiveProperty Active { get; } public ItemManager ItemManager { get; } - public Subject AudioEvents { get; } = new Subject(); - public Subject<(uint id, float v)> AudioParameters { get; } = new Subject<(uint id, float v)>(); - public Dictionary AudioParameterValues { get; } = new Dictionary(); - private float oldTemperature; public float Temperature { @@ -2190,77 +2185,6 @@ public class EquippedItem : IStatContext } } - public void FireAudioEvent(uint eventId, bool skipVerify = false) - { - if(SoundBank != null && (skipVerify || SoundBank.IncludedEvents.Any(o => o.Id == eventId))) - AudioEvents.OnNext(eventId); - } - - public void FireAudioEvent(WwiseSoundBinding soundBinding) - { - FireAudioEvent(soundBinding.PlayEvent); - } - - public void PlaySound(WwiseLoopingSoundBinding soundBinding) - { - FireAudioEvent(soundBinding.PlayEvent); - } - - public void StopSound(WwiseLoopingSoundBinding soundBinding) - { - FireAudioEvent(soundBinding.StopEvent); - } - - public void FireAudioEvent(WeaponAudioEvent weaponAudioEvent) - { - if (SoundBank == null) return; - var eventObject = SoundBank.GetEvent(weaponAudioEvent); - if (eventObject == null) - { - ItemManager.Log($"Attempted to trigger {Enum.GetName(typeof(WeaponAudioEvent), weaponAudioEvent)} weapon audio event, but the soundbank doesn't support it!"); - return; - } - FireAudioEvent(eventObject.Id, true); - } - - public void FireAudioEvent(ChargedWeaponAudioEvent weaponAudioEvent) - { - if (SoundBank == null) return; - var eventObject = SoundBank.GetEvent(weaponAudioEvent); - if (eventObject == null) - { - ItemManager.Log($"Attempted to trigger {Enum.GetName(typeof(ChargedWeaponAudioEvent), weaponAudioEvent)} weapon audio event, but the soundbank doesn't support it!"); - return; - } - FireAudioEvent(eventObject.Id, true); - } - - public void SetAudioParameter(uint id, float v, bool skipVerify = false) - { - if (SoundBank != null && (skipVerify || SoundBank.GameParameters.Any(o => o.Id == id))) - { - AudioParameterValues[id] = v; - AudioParameters.OnNext((id, v)); - } - } - - // public void SetAudioParameter(WwiseParameterBinding binding) - // { - // FireAudioEvent(binding.Parameter); - // } - - public void SetAudioParameter(SpecialAudioParameter p, float v) - { - if (SoundBank == null) return; - var metaObject = SoundBank.GetParameter(p); - if (metaObject == null) - { - ItemManager.Log($"Attempted to set {Enum.GetName(typeof(ChargedWeaponAudioEvent), p)} audio parameter, but the soundbank doesn't support it!"); - return; - } - SetAudioParameter(metaObject.Id, v, true); - } - public EquippedItem(ItemManager itemManager, EquippableItem item, int2 position, Entity entity, HardpointData hardpoint) { ItemManager = itemManager; @@ -2460,11 +2384,6 @@ public class EquippedItem : IStatContext public void Update(float delta) { - foreach (var audioStat in Data.AudioStats) - { - SetAudioParameter(audioStat.Parameter, Evaluate(audioStat.Stat)); - } - if (Active.Value) { foreach (var group in BehaviorGroups.Values) diff --git a/Assets/Scripts/ServerShared/Enums.cs b/Assets/Scripts/ServerShared/Enums.cs index cbd970c3f..63d2674db 100644 --- a/Assets/Scripts/ServerShared/Enums.cs +++ b/Assets/Scripts/ServerShared/Enums.cs @@ -203,34 +203,6 @@ public enum TemperatureUnit Fahrenheit } -public enum WeaponAudioEvent -{ - Fire, - Hit, - Miss -} - -public enum ChargedWeaponAudioEvent -{ - Start, - Stop, - Fail -} - -public enum SpecialAudioParameter -{ - ShipVelocity, - ChargeLevel, - TargetLock, - Intensity, -} - -public enum LoopingAudioEvent -{ - Play, - Stop -} - public enum MusicType { Overworld, diff --git a/Assets/Scripts/ServerShared/WwiseMetadata.cs b/Assets/Scripts/ServerShared/WwiseMetadata.cs deleted file mode 100644 index 30b88ad29..000000000 --- a/Assets/Scripts/ServerShared/WwiseMetadata.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; - -[JsonObject] -public class WwiseMetadataFile -{ - public WwiseMetaSoundBanksInfo SoundBanksInfo; -} - -[JsonObject] -public class WwiseMetaSoundBanksInfo -{ - public WwiseMetaSoundBank[] SoundBanks; - - private Dictionary _soundBanks; - public WwiseMetaSoundBank GetSoundBank(uint id) - { - if (_soundBanks == null) _soundBanks = SoundBanks.ToDictionary(sb => sb.Id); - return _soundBanks[id]; - } - - private Dictionary _soundBankNames; - public WwiseMetaSoundBank GetSoundBank(string name) - { - if (_soundBankNames == null) _soundBankNames = SoundBanks.ToDictionary(sb => sb.ShortName); - return _soundBankNames[name]; - } -} - -[JsonObject] -public class WwiseMetaSoundBank -{ - public uint Id; - public string ShortName; - public string ObjectPath; - public WwiseMetaObject[] IncludedEvents; - public WwiseMetaObject[] GameParameters; - - public WwiseMetaObject GetEvent(WeaponAudioEvent weaponAudioEvent) - { - return weaponAudioEvent switch - { - WeaponAudioEvent.Fire => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_fire")), - WeaponAudioEvent.Hit => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_hit")), - WeaponAudioEvent.Miss => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_miss")), - _ => throw new ArgumentOutOfRangeException(nameof(weaponAudioEvent), weaponAudioEvent, null) - }; - } - - public WwiseMetaObject GetEvent(ChargedWeaponAudioEvent chargedWeaponAudioEvent) - { - return chargedWeaponAudioEvent switch - { - ChargedWeaponAudioEvent.Start => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_charge_play")), - ChargedWeaponAudioEvent.Stop => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_charge_stop")), - ChargedWeaponAudioEvent.Fail => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_fail")), - _ => throw new ArgumentOutOfRangeException(nameof(chargedWeaponAudioEvent), chargedWeaponAudioEvent, null) - }; - } - - public WwiseMetaObject GetEvent(LoopingAudioEvent loopingAudioEvent) - { - return loopingAudioEvent switch - { - LoopingAudioEvent.Play => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_play")), - LoopingAudioEvent.Stop => IncludedEvents?.FirstOrDefault(e => e.Name.EndsWith("_stop")), - _ => throw new ArgumentOutOfRangeException(nameof(loopingAudioEvent), loopingAudioEvent, null) - }; - } - - public WwiseMetaObject GetParameter(SpecialAudioParameter audioParameter) - { - return audioParameter switch - { - SpecialAudioParameter.ShipVelocity => GameParameters?.FirstOrDefault(p => p.Name == "ship_velocity"), - SpecialAudioParameter.ChargeLevel => GameParameters?.FirstOrDefault(p => p.Name == "charge_level"), - SpecialAudioParameter.TargetLock => GameParameters?.FirstOrDefault(p => p.Name == "target_locking"), - SpecialAudioParameter.Intensity => GameParameters?.FirstOrDefault(p => p.Name == "sfx_shared_intensity"), - _ => throw new ArgumentOutOfRangeException(nameof(audioParameter), audioParameter, null) - }; - } -} - -[JsonObject] -public class WwiseMetaObject -{ - public uint Id; - public string Name; - public string ObjectPath; -} \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/WwiseMetadata.cs.meta b/Assets/Scripts/ServerShared/WwiseMetadata.cs.meta deleted file mode 100644 index d9deda43b..000000000 --- a/Assets/Scripts/ServerShared/WwiseMetadata.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 0a12363ee8ef43b399bf91ca099947a9 -timeCreated: 1619664281 \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/WwiseSoundBinding.cs b/Assets/Scripts/ServerShared/WwiseSoundBinding.cs deleted file mode 100644 index da7a97548..000000000 --- a/Assets/Scripts/ServerShared/WwiseSoundBinding.cs +++ /dev/null @@ -1,22 +0,0 @@ -using MessagePack; -using Newtonsoft.Json; - -[MessagePackObject, JsonObject(MemberSerialization.OptIn)] -public class WwiseSoundBinding -{ - [Key(0), JsonProperty("playEvent")] - public uint PlayEvent; -} - -[MessagePackObject, JsonObject(MemberSerialization.OptIn)] -public class WwiseLoopingSoundBinding : WwiseSoundBinding -{ - [Key(1), JsonProperty("stopEvent")] - public uint StopEvent; -} - -// public class WwiseParameterBinding -// { -// [Key(0), JsonProperty("parameter")] -// public uint Parameter; -// } \ No newline at end of file diff --git a/Assets/Scripts/ServerShared/WwiseSoundBinding.cs.meta b/Assets/Scripts/ServerShared/WwiseSoundBinding.cs.meta deleted file mode 100644 index b996ffa72..000000000 --- a/Assets/Scripts/ServerShared/WwiseSoundBinding.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2e128c1cb68f481c9a846344e8283014 -timeCreated: 1619729875 \ No newline at end of file diff --git a/tests/Aetheria.Shared.Tests/FireControlPerWeaponTests.cs b/tests/Aetheria.Shared.Tests/FireControlPerWeaponTests.cs index 1d8f9f6be..21525805c 100644 --- a/tests/Aetheria.Shared.Tests/FireControlPerWeaponTests.cs +++ b/tests/Aetheria.Shared.Tests/FireControlPerWeaponTests.cs @@ -441,7 +441,6 @@ public sealed class FireControlPerWeaponTests : IDisposable { public int Ammo; public float ChargeSpent; - public int Sounds; public int Wears; public float Heat; public bool Visible; @@ -451,7 +450,7 @@ public sealed class FireControlPerWeaponTests : IDisposable } // One discrete weapon, triggered once at no target, with every cost observable: a magazine, an energy charge, - // a sound bank, wear events, heat and visibility. Range 29.5 refuses (arming 30); Range 40 fires. + // wear events, heat and visibility. Range 29.5 refuses (arming 30); Range 40 fires. private Costs Pull(float range, bool single, bool viaTrigger, bool staleRange = false, bool auto = false) { var r = Build(fuse: WeaponFuse.Proximity, blast: 30f, range: range, energy: 50f, heat: 5000f, visibility: 100f, magazine: 5, singleAmmoBurst: single, auto: auto); @@ -459,9 +458,7 @@ public sealed class FireControlPerWeaponTests : IDisposable Aim(r, float2(0, 1)); var weapon = (InstantWeapon) r.Gun.Weapon; var capacitor = (InputCapacitor) typeof(InstantWeapon).GetField("_capacitor", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(weapon); - r.Gun.Item.SoundBank = new WwiseMetaSoundBank { IncludedEvents = new[] { new WwiseMetaObject { Id = 7, Name = "gun_fire" } } }; var costs = new Costs(); - r.Gun.Item.AudioEvents.Subscribe(_ => costs.Sounds++); r.Zone.ShotCommitted.Subscribe(_ => costs.Shots++); // a fused round with no flight commits and resolves in its own tick r.Shooter.ItemDamage.Subscribe(t => { if (t.Item1 == r.Gun.Item) costs.Wears++; }); weapon.OnFire += _ => costs.Announced++; @@ -493,12 +490,12 @@ public sealed class FireControlPerWeaponTests : IDisposable } // Control: the same weapon with Range to spare pays every cost, so a free refusal below is not a fixture that - // never spends. Then the refusal costs nothing: no ammo, no energy, no sound, no wear, no heat, no + // never spends. Then the refusal costs nothing: no ammo, no energy, no announcement, no wear, no heat, no // visibility, no shot. `single` is a weapon that pays once per burst, at its first unrefused round rather than at each; // `viaTrigger` false authorises the burst directly (the way a trigger that passed leaves it) on a weapon whose // Range is short, so the Trigger check cannot be what stops the round and Execute must refuse it itself. // Kills, one per row of the assertions: a spend that precedes the refusal (Execute or Trigger), an - // announcement, a sound, wear, heat or visibility left ahead of the `continue`. + // announcement (what a presenter hears), wear, heat or visibility left ahead of the `continue`. [Theory] [InlineData(false, true)] [InlineData(true, true)] @@ -509,7 +506,6 @@ public sealed class FireControlPerWeaponTests : IDisposable Assert.True(fired.Shots == 1, $"shots {fired.Shots}"); Assert.True(fired.Ammo == 1, $"ammo spent {fired.Ammo}"); Assert.True(fired.ChargeSpent > 1f, "a fired round spends its energy"); - Assert.Equal(1, fired.Sounds); Assert.True(fired.Wears > 0); Assert.True(fired.Heat > 0f); Assert.True(fired.Visible); @@ -519,7 +515,6 @@ public sealed class FireControlPerWeaponTests : IDisposable Assert.Equal(0, refused.Shots); Assert.Equal(0, refused.Ammo); Assert.Equal(0f, refused.ChargeSpent); - Assert.Equal(0, refused.Sounds); Assert.Equal(0, refused.Wears); Assert.True(fired.Heat - refused.Heat > 5f, $"a refused round adds no heat ({refused.Heat} vs {fired.Heat})"); Assert.False(refused.Visible); @@ -721,26 +716,23 @@ public sealed class FireControlPerWeaponTests : IDisposable Assert.True(refused.CanFire, "a burst that fired nothing leaves no cooldown"); } - // A refused charged weapon never starts charging: no charge heat, no audio, no start event, and it can be - // triggered again at once. The control (Range 40) charges, sounds and heats. + // A refused charged weapon never starts charging: no charge heat, no start event a presenter could sound, and it can be + // triggered again at once. The control (Range 40) charges and heats. // Kills: ChargedWeapon.Activate that does not ask FireControl. - private (int Starts, int Sounds, float Heat, bool Charging) Charge(float range) + private (int Starts, float Heat, bool Charging) Charge(float range) { var r = Build(charged: true, fuse: WeaponFuse.Proximity, blast: 30f, range: range); r.Shooter.SetTarget(TargetRef.None); Aim(r, float2(0, 1)); var weapon = (ChargedWeapon) r.Gun.Weapon; - r.Gun.Item.SoundBank = new WwiseMetaSoundBank { IncludedEvents = new[] { new WwiseMetaObject { Id = 7, Name = "gun_charge_play" } } }; var starts = 0; - var sounds = 0; weapon.OnStartCharging += () => starts++; - r.Gun.Item.AudioEvents.Subscribe(_ => sounds++); var heatBefore = r.Gun.Item.Temperature; weapon.Activate(); for (var i = 0; i < 3; i++) r.Zone.Update(.1f); - return (starts, sounds, r.Gun.Item.Temperature - heatBefore, weapon.Progress > 0f); + return (starts, r.Gun.Item.Temperature - heatBefore, weapon.Progress > 0f); } [Fact] @@ -748,12 +740,10 @@ public sealed class FireControlPerWeaponTests : IDisposable { var fired = Charge(40f); Assert.Equal(1, fired.Starts); - Assert.True(fired.Sounds > 0, "control: charging sounds"); Assert.True(fired.Heat > 0f, "control: charging heats"); var refused = Charge(29.5f); Assert.Equal(0, refused.Starts); - Assert.Equal(0, refused.Sounds); Assert.True(fired.Heat - refused.Heat > 5f, $"a refused weapon adds no charge heat ({refused.Heat} vs {fired.Heat})"); } // A triggered burst has not started its cooldown, but it is not ready either: pulled again before its first round