Serverside Sound System #49
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Adding a Server controlled Sound System
Summary
this fork adds a way to play sounds on the client & load new sounds from the web, it currently supports:
Loading sounds by URL to create custom Sound Definitions
Triggering Sounds via RPC call & UI Component
you can see a demo of its features here ⇒ https://streamable.com/dc8vp3
Why?
Giving devs a way to reliable & controlled way to play sound effects
the somewhat recent changes to gun sound effects & the crazy amount of people being upset over it tells us that sound & sound effects matter.
Until now, as a plugin developer, it was tedious & limiting to add sound to your mechanics.
You could play some Rust sound effects via the effect network, create a hidden NPC & send sound as voice packets, or make use of Radios & Cassettes to play sounds from the web.
However, this brought along a large amount of limitations on both the quality, timing & performance of the sound & its experience.
The Breakdown
this fork has 2 parts:
There are 3 RPC calls that a server can use with the Sound System.
RPC: AddSoundDefinition
[{ "name":"nameOfYourDefinition", "url": "https://page.tld/path/to/your/file.wav", // supports some other filetypes aswell "loop" : false, // if true the sound will loop and wont stop until you manually do so "category" : "voice", // sets the volume setting to use "repeat" : 5, // how often to repeat the animation, optional (Default = 0), set to -1 to repeat indefinitely "volumeDiff" : 0.0, // the random volume offset each time the sound is played "pitch" : 1.0, // the pitch of the sound "pitchDiff" : 0.0, // the random pitch offset each time the sound is played "falloffCurve" : [ // sets a custom curve to use "0 1 0 0", // each item in the array is a string of 4 floats from which a keyframe is constructed "1 0 0 0" // these keyframes are turned into an AnimationCurve which controls the custom curve ], "spatialBlendCurve" : [ // curves are scaled from 0 to 1, then scaled to the maxDistance of the Audio Source "0 1 0 0", "1 0 0 0" ], "spreadCurve" : [ "0 1 0 0", "1 0 0 0" ] }]RPC: PlaySound
[{ "instanceName":"nameOfYourSoundInstance", "definition": "nameOfYourDefinition", // to play a Rust sound instead, give it the asset path (starting with assets/content/...) "fadeIn" : 0.1, // fades in volume over time "parent" : 61340, // the net id of the entity to parent the sound to "offset" : "0 0.3 3", // the position to offset your sound, if a sound isnt parented and has no offset it will act as a first person sound "maxDistance" : 150.0, // the max distance the sound can be heard from, custom curves in the sound definition scale by this amount "dopplerScale" : 1.0, // the scale of the doppler effect when moving towards or away from the sound (if not first person) }]RPC: StopSound
[{ "instanceName":"nameOfYourSoundInstance", "fadeOut" : 0.1, // fades out your sound before stopping it "kill" : true, // decides if the sound instance should be killed, if its killed any follow-up calls to StartSound will have to recreate the sound, whereas otherwhise it would just replay the existing sound instance }]UI Implementation
This fork adds the SoundTrigger Component which can play multiple sounds based on mouse interactions, you can attach it to any panel & it will react to click & hover events on it or its children.
{ "type": "SoundTrigger", "sounds": [ { "trigger": "Hover", // trigger type, either "Hover" or "Click" "definitionToPlay": "assets/content/sound/sounddefinitions/entities/helicopter/helicopter-rocket-fire-single.asset", // the definition name you created or the path to the Rust asset "fadeIn": 0.1, "killOnExit" : false, // if false it will play the sound until its done, if true it will fadeOut/stop the sound when unhovering the panel "fadeOut": 0.2 } ] }Issues, features I couldn't implement & a note on my test setup
I can't guarantee that this will be a flawless implementation because of the way I chose to create my test setup.
When making this feature, I didn't want to recreate what rust already has, so working with the “Sound” and "SoundDefinition" classes was the obvious way to go since it would also allow us to play Rust's sounds.
To recreate this I ended up using a mix of code from the server DLLs, current client DLLs (decompiled into stubs) and decompilable client files from back in 2018, since that was before rust changed to IL2CPP.
So while I did get it working, there were some bugs in my test setup that I couldn't confirm would appear in the final implementation:
maxDistance gets set to 500 every frame
I couldn't find anything in the code I used or online about why this happened, but it happens both when setting it via the editor or via the JSON property.
The falloff Curve stayed at logarithmic even when setting a custom falloffCurve
The falloff custom curve does get set, when manually switching it over to custom curve it will use the curve that was set, but I wasn't able to find out why this doesn't happen automatically.
On a note of features I couldn't implement, there are 2 things that may need some attention
When setting the category for a sound, I simply set the volume of the SoundDefinition, but this probably isn't how sound settings are actually used in rust, so I'd recommend changing it to match the real implementation.
A feature I would have loved to implement is the ability to prevent Rust's in game music from playing if we want to play our own.
I didn't want to alter the user's setting directly, so something like a ConVar is probably a better way to add this feature.
wrapping up
The sound system should be a solid baseline for developers to play their own sound effects & gives us access to a lot of Rust's great sounds.
There could be some hiccups though when implementing it due to my lack of knowledge on rust's sound system.