I need help making a MUSIC GUI where all players can hear, k everything updates but buggy omg

The song GUI doesn’t update what song is playing for that server as well, and also It’s a normal script, not a local script.

So you want to have a system that loops through the songs in a folder and plays them?

Yes, throughout the server it plays on the server, so when a player joins a game, it hears that same song everyone else is listening to, and the gui changes to that song as well

Can you guide me on what to do?

Oh yes sorry, I got distracted. However, note, that I’m not going to be doing it so that everybody hears the same song, it’s a little complex for your current skill (hopefully one day you’ll be able to).

So the first thing you need to do is make a table, which is basically a big lump of organized values under 1 variable. To do that, all we have to do is

--Note, this script is a local script inside StarterPlayerScripts
local SongsFolder = game.Workspace:WaitForChild("Songs"):GetChildren() --We use "WaitForChild" so that way the game doesn't bug out

When we say :GetChildren() we’re saying get all the children of the folder “songs.”
Here is an example of what a parent-child relationship looks like in the explorer:
image

Next what we want to do is loop through the table that we set previously (SongsFolder) using a for loop. Assuming i stands for “index” and v stands for “value,”

for i, v in pairs(SongsFolder) do --Go through the songs folder
  v:Play() --Play the song
  wait(v.TimeLength) --Wait for it to end
end

However, since this loop will stop repeating itself after it has gone through all the songs, what we have to do is put that loop inside a while loop, like so:

while wait(1) do
  for i, v in pairs(SongsFolder) do --Go through the songs folder
    v:Play() --Play the song
    wait(v.TimeLength) --Wait for it to end
  end
end

This will make it so that even after it loops through the whole folder, it will repeat again; therefore making it so they will never stop playing.

Our final code should look like this.

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
--The above is here just to make sure the songs don't start playing too early (before loading)

local SongsFolder = game.Workspace:WaitForChild("Songs"):GetChildren()

while wait(1) do
	for i, v in pairs(SongsFolder) do --Go through the songs folder
		v:Play() --Play the song
		wait(v.TimeLength) --Wait for it to end
	end
end
1 Like

A noteworthy thing, using wait() can introduce unexpected delays and such. It’s probably better to use Sound | Roblox Creator Documentation to register when the sound ended, and with the new task library, wait() has been improved upon, mostly eliminating the throttling issues with wait().

Another thing to note, typically in game music flows better with a small wait in-between each song.

One other thing to note, pairs() doesn’t run things in a particular order, so if you want it to be consistent, you can use ipairs().

Last note, Players | Roblox Creator Documentation only works in LocalScripts, and as noted here:

With all these tweaks, this:

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
--The above is here just to make sure the songs don't start playing too early (before loading)

local SongsFolder = game.Workspace:WaitForChild("Songs"):GetChildren()

while wait(1) do
	for i, v in pairs(SongsFolder) do --Go through the songs folder
		v:Play() --Play the song
		wait(v.TimeLength) --Wait for it to end
	end
end

would become this:

local SongsFolder = game.Workspace:WaitForChild("Songs"):GetChildren()

while true do
	for i, v in ipairs(SongsFolder) do --Go through the songs folder
		v:Play() --Play the song
		v.Ended:Wait() --Wait for it to end
		task.wait(3) -- 3 second delay between songs, optional
	end
end
1 Like

k I got it working but the only thing I need help on, is how do I make it so the GUI changes with the song name in starter GUI, whenever a player joins and is in game.

Is the script playing the songs a local script or a server script?

Server script, as noted in post #2

It’s just playing in workspace in a folder, with that script I’ve mentioned in the folder and that’s it.

What you can do is use RemoteEvent:FireAllClients() and send the song name through that. Put a remote event in Replicated Storage named “SongNameRE,” and assuming you’re using @Inconcludable’s script, you’d change it to:

local SongsFolder = game.Workspace:WaitForChild("Songs"):GetChildren()

while true do
	for i, v in ipairs(SongsFolder) do --Go through the songs folder
		v:Play() --Play the song
		game.ReplicatedStorage.SongNameRE:FireAllClients(v.Name)

		v.Ended:Wait() --Wait for it to end
		task.wait(3) -- 3 second delay between songs, optional
	end
end

And then as a local script (in StarterPlayerScripts), you’d put

game.ReplicatedStorage.SongNameRE.OnClientEvent:Connect(function(SongName)
	--Set the player's screen gui text to SongName
end

Make sure you set the player variable too, preferrably above the event listener.

It’s just a normal script, and it works… But the only thing I need to do now is so the starter GUI matches the text as the song is currently playing, and in the workspace with my songs folder, and it has a script in that exact folder just looks like this like I’ve mentioned…

while true do
	
	local l__Songs__1 = game.Workspace.Songs;
	
	
	wait(0.1);
	l__Songs__1.WalkMeHome.Playing = false;
	l__Songs__1.SubZero.Playing = true;
	wait(120.084);
	
	l__Songs__1.SubZero.Playing = false;
	l__Songs__1.SlowMotion.Playing = true;
	wait(120.216);
	
	l__Songs__1.SlowMotion.Playing = false;
	l__Songs__1.JustForTheNight.Playing = true;
	wait(80.169);
	
	l__Songs__1.JustForTheNight.Playing = false;
	l__Songs__1.JocelynFlores.Playing = true;
	wait(117.472);
	
	l__Songs__1.JocelynFlores.Playing = false;
	l__Songs__1.Hotel.Playing = true;
	wait(327.523);
	
	l__Songs__1.Hotel.Playing = false;
	l__Songs__1.NoTearsLeftToCry.Playing = true;
	wait(208.143);
	
	l__Songs__1.NoTearsLeftToCry.Playing = false;
	l__Songs__1.UpLikeAnInsomniac.Playing = true;
	wait(87.536);
	
	l__Songs__1.UpLikeAnInsomniac.Playing = false;
	l__Songs__1.JocoleynFlores.Playing = true;
	wait(117.472);
	
	l__Songs__1.JocoleynFlores.Playing = false;
	l__Songs__1.xSupply.Playing = true;
	wait(84.816);
	
	l__Songs__1.xSupply.Playing = false;
	l__Songs__1.LensV2.Playing = true;
	wait(100);
	l__Songs__1.LensV2.Playing = false;
	l__Songs__1.AllTheWayUp.Playing = true;
	wait(195.291);
	
	l__Songs__1.AllTheWayUp.Playing = false;
	l__Songs__1.GetYou.Playing = true;
	wait(277.75999999999993);
	
	l__Songs__1.GetYou.Playing = false;
	l__Songs__1.HowToSaveALife.Playing = true;
	wait(76.79999999999971);
	
	l__Songs__1.HowToSaveALife.Playing = false;
	l__Songs__1.BarbieDrip.Playing = true;
	wait(108.14799999999961);
	l__Songs__1.BarbieDrip.Playing = false;
end;

All I need to do is just make sure StarterGUI matches that name of the song whenever someone joins the game, the GUI auto updates to that exact song playing.

(Note that this will make it so that players who have recently joined won’t have the music playing, as the server still thinks no songs are playing)

1 Like

it works in game? Whenever I rejoin or leave and go back, still plays the servers song.

Hmm, this makes it a bit more complex. A possible solution is to store the song in an ObjectValue | Roblox Creator Documentation every time the song changes. With modifications to the previous code I provided, it would look like this:

local SongsFolder = game.Workspace:WaitForChild(“Songs”):GetChildren()

while true do
	for i, v in ipairs(SongsFolder) do --Go through the songs folder
		if v:IsA("Sound") then
			SongsFolder.SongPlaying.Value = v 
-- You will need to create an object value in "SongsFolder" named "SongPlaying"
			v:Play() --Play the song
			v.Ended:Wait() --Wait for it to end
			task.wait(3) -- 3 second delay between songs, optional
		end
	end
end

To get the name of the song on the client, you can bind an event to the ObjectValue changing. Here’s an example:

local SongFolder = workspace:WaitForChild("SongsFolder", 30)
if not SongFolder then error("Unable to locate song folder!") end
local SongPlayingValue = SongFolder:FindFirstChild("SongPlaying")
if not SongPlayingValue then error("Unable to locate song ObjectValue!") end

--// Use this space to change the Playing song name/TextLabel, as the 
--// .Changed event will not fire since a song is already playing

SongPlayingValue.Changed:Connect(function(song)
	if song then
		--Use this space to change the Playing song name/TextLabel
	end
end)

If you have any issues with this, let me know.

I’m just gonna use a string value, and update it everytime when the song changes and change to that name.

How do I change the string value in a script?

You set the StringValue | Roblox Creator Documentation property to whatever the string is, like:

StringValue.Value = "This is a string"

or

StringValue.Value = ExampleProperty.Name

I have it like this

	
	wait(0.1);
	l__Songs__1.WalkMeHome.Playing = false;
	currentTrack.Value = Name

Did you ever define what the “Name” variable was?