Play sound on client then replicate it to other players to avoid latency?

The topic title is pretty self-explanatory. I want to play a sound on the client and fire a remote to the server, so the client hears the sound first (with no delay) and the other clients take a while to hear it, due to ping.

I’ve looked at a few topics, and some of them tell you to play the sound on the client, fire a remote to the server, play the sound on the server, fire it back to the client and set the volume of the new sound to 0 on the client, which I don’t like.

PlaySound function:

function Utilities:CreateSound(Template: Sound, Parent: Instance, Properties: {[string]: any}, DontReplicate: boolean): Sound
	if RunService:IsClient() and not DontReplicate then
		SoundRemote:FireServer(Template, Parent, Properties, true)
	end

	local Sound = Template:Clone()
	if Properties then
		Utilities:SetProperties(Sound, Properties)
	end

	Sound.SoundGroup = (Properties and Properties.SoundGroup == nil and SoundGroup) or Sound.SoundGroup
	Sound.Parent = Parent
	Sound:Play()
	Utilities:EndSound(Sound)

	return Sound
end

Client replication code:

-- [ Services ] --
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- [ Service constants ] --
local Resources = ReplicatedStorage.Resources
local Events = Resources.Events

-- [ Modules ] --
local Utilities = require(script.Parent)

-- [ Network ] --
local SoundRemote = Events.Sound
SoundRemote.OnClientEvent:Connect(function(Template: Sound, Parent: Instance, Properties: {[string]: any}, DontReplicate)
	Utilities:CreateSound(Template, Parent, Properties, DontReplicate)
end)

Server replication code:

-- [ Services ] --
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

-- [ Service constants ] --
local Resources = ReplicatedStorage.Resources
local Events = Resources.Events

-- [ Network ] --
local SoundRemote = Events.Sound
SoundRemote.OnServerEvent:Connect(function(Sender, Template: Sound, Parent: Instance, Properties: {[string]: any})
	for _, Player in Players:GetPlayers() do
		if Player ~= Sender then
			SoundRemote:FireClient(Player, Template, Parent, Properties, true)
		end
	end
end)

Should this work?

You could instead play the sound on the client and then send a remote event to the server that fires a remote event to all other clients that will then hear the sound, which avoids the issue of sending a remote event back to the original client.

1 Like

Unless you can predict when the sound needs to play it’s almost impossible to avoid latency.

If a player has 200 ms ping it’s going to take at least 1/5th of a second for the sound to play for them, no way around that.

Doesn’t matter whether you play the sound on the server or whether you fire a remote event, the latency is always going to be there.
Playing a sound on the server just sends a invisible remote signal under the hood that you don’t see.

What exactly is the sound that you are trying to play?
Knowing more context might help find alternative solutions.

1 Like

I mentioned this in the topic already.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.