Using a RemoteEvent, Sound.TimePosition will set via cmd bar, but will not set via server script?

I know the title is a little misleading, but it’s close to what I am asking.

  1. What do you want to achieve? I am trying to set the TimePosition of 2 sounds when a new client joins.

  2. What is the issue? For some reason, it won’t actually set. Basically, all you need to know is that there are 3 scripts: a LocalScript in a GUI, a Script in ServerScriptService, and a LocalScript in StarterCharacterScripts. I am making a music/DJ system, and I am using Client-Server-Client to manipulate the sounds with RemoteEvents. However, I want new clients to get the same music (or close to it) that existing clients have. There are variables for various parts of a Sound that can be set by this system. When a new client joins, it syncs this information with the client so it has the sounds correct. However, we are worried about TimePosition. When I run :FireClient on the RemoteEvent I am using, it gets to the client alright (verified via print() statements) and it seems to set it (again, verified via print() statements). However, when I go to play the music, it is NOT at the place it should be at (I know this because I have been setting it to a different value for testing). It tends to be at 0 or where it was paused last. I cannot figure out what is causing this. What is also even weirder is that I can go into Studio “Server” perspective, and use the command bar to :FireClient my testing client and a time position, and when I go back to the client and play the music, IT WORKS. No idea what could be causing this.

  3. What solutions have you tried so far? I have seriously gone around, tried to modify code, etc but what puts me off is the fact that pretty much the exact same call to the same RemoteEvent works through the server side command bar, but not via a server side script. I have looked at the various articles on the DevHub but I can’t seem to have done anything wrong.

Below is the code that is important, the top one is what runs when a client joins, the bottom one is what runs when the Sync RemoteEvent has :FireClient run on it. Only the bottom one runs when I fired the RemoteEvent from the server, and the value for the time position coming from the server script is not a string and it is not lost or set to 0 or nil.

--Script in ServerScriptService
--in the PlayerAdded function
game.ReplicatedStorage.ChangeID:FireClient(player,IDV)
game.ReplicatedStorage.ChangeVolume:FireClient(player,volumeV)
game.ReplicatedStorage.ChangeRepeat:FireClient(player,loopedV)
game.ReplicatedStorage.Sync:FireClient(player,positionV)
wait(0.1)
if playingV == true then
	game.ReplicatedStorage.Play:FireClient(player)
end
--LocalScript in StarterCharacterScripts
--print statements for testing
--in the OnClientEvent function for the Sync RemoteEvent
print("synced with time"..timeP)
part2.Sound.TimePosition=timeP
part1.Sound.TimePosition=timeP
print(part1.Sound.TimePosition)

Really hope you could help, as I am new to Roblox programming and I don’t know what could be causing this.
Also please don’t comment

This could be more efficient in x way

because I am not looking for efficiency help.

Where did you define

local timeP

local timeP
is a variable passed in when the RemoteEvent Sync, mentioned above, has a :FireClient used on it, it is supposed to be a double if passed in correctly (and yes it is passed in correctly)

Here’s a better example: in this video I: show you the print statements showing that the sync seemed to be successful, play the music to show that it starts at the beginning, then went to the server, fired me, the client, using the same RemoteEvent, then went back as the client and showed that it had worked there.
Fixed the audio, here’s the new revised clip
The audio used is this: https://www.roblox.com/library/1844837666/Clarinet-Swing


If you want to know what’s printing:
When sync is called on client add and when I manually call it, it says “synced with time(time in seconds)”
When I hit pause it prints “(time in seconds not rounded)”
And no, the play button does not call Sound:Play(), it calls Sound:Resume()

Not sure why it didn’t work, but I recommend using remotefunctions instead since it look like you’re expecting the client to be ready without knowing it is ready. This will propably fix the problem you’re having.

…Except it still doesn’t work if I wait like 20 seconds, how would the client not be ready after that?

Here, do you need to fire the client 4-5 times? Couldn’t you just do it once?

game.ReplicatedStorage.Sync:FireClient(player,IDV,volume,loopedV,postitionV)

Good point, but it still probably won’t fix the problem with the times not setting.

Could you show your entire client script for receiving Variables and playing the sound?

local rs = game:GetService("ReplicatedStorage")
wait(1)
local part1 = workspace.TheStage.SpeakerParts.Speaker1
local part2 = workspace.TheStage.SpeakerParts.Speaker2
rs.Play.OnClientEvent:Connect(function()
	spawn(function() part1.Sound:Resume()end)
	spawn(function() part2.Sound:Resume()end)
end)
rs.Pause.OnClientEvent:Connect(function()
	local timeP = part1.Sound.TimePosition
	print(timeP)
	spawn(function() part1.Sound:Pause() part1.Sound.TimePosition=timeP end)
	spawn(function() part2.Sound:Pause() part2.Sound.TimePosition=timeP end)
end)
rs.Stop.OnClientEvent:Connect(function()
	part1.Sound:Stop()
	part2.Sound:Stop()
end)
rs.ChangeID.OnClientEvent:Connect(function(id)
	spawn(function() part1.Sound.TimePosition=0 part1.Sound.SoundId=id end)
	spawn(function() part2.Sound.TimePosition=0 part2.Sound.SoundId=id end)
end)
rs.ChangeVolume.OnClientEvent:Connect(function(vol)
	part1.Sound.Volume=vol
	part2.Sound.Volume=vol
end)
rs.Sync.OnClientEvent:Connect(function(timeP)
	print("synced with time"..timeP)
	part2.Sound.TimePosition=timeP
	part1.Sound.TimePosition=timeP
	print(part1.Sound.TimePosition)
end)```

spawn(function())s are for making the two speakers line up in time position as closely as possible.

Are there statements above the PlayerAdded which yield, E.G. a WaitForChild? You might find when you first join the game, this PlayerAdded connection has not yet been made because something is yielding

I know that I should add a waitForChild, however for testing there is a wait(15) statement and my client is loaded in by then in studio.

The problem is the reverse of what you said: the client, I think, is loading in before the PlayerAdded:Connect line is executed.

That means:

  • Player joins
  • PlayerAdded:Connect(function()) executes
  • Because the Player joins before the PlayerAdded connection is made, it doesn’t fire for that player

Try making the PlayerAdded:Connect the very first line of code in the server sided script and see if that fixes anything.

Still does not work (granted it isn’t on line 1, it is after required local variables)

Type print(“hello from the server side”) inside the playeradded function and see if it’s firing?

So essentially, do you want me to have it do the stuff before the client loads in? If I do it first thing, it will throw an error because the workspace isn’t loaded in, so there has to be a delay of some sort, and I really don’t think the client loaded/not loaded thing is the problem.

It is firing, as there are print statements inside the Sync.onClientEvent:Connect() and they are printing, in fact one of them prints the value of TimePosition in one of the speakers and it seems to set, yet it actually hasn’t if you look in the explorer or play the music.

I’ve had a friend DMing me on Discord this whole time, and he tested my scripts (I sent them) on his own game, and it worked, so now the question is what could be preventing it in my world from not working in the script.

You might need to have, inside the client, wait statements that delay any code execution until what needs to load in loads in. Something like:

OnClientEvent:Connect(function())
while not loaded do wait() end
– Code

Alright. Weird story time. Somehow, the function for changing the ID was taking LONGER to change the ID and the server script fired Sync and Sync in the client beat the ChangeID to the changing the time position. Why does ChangeID change the time position? So we couldn’t have people changing the ID while it was playing and it starts in an odd place. Adding even a tiny amount of delay after firing ChangeID allowed it to work. This was odd, stupidly odd.

1 Like