Music Array Playlist Table Change (Please help) not working

Hello,
So basically, I want my music playlist table player to keep playing a the music inside of the assigned table and waits for the music to be finished and plays the next songs and wraps all back together.
The music playlist (table) is only supposed to change when the table from the bindableevent is different from the previous table.


Music playlist script:

local r = {}
script.Event.Event:Connect(function(s)
	local log = true
	if #r~=#s then
		log = false
	end
	for i = 1,#r do
		if i>1 then
			if log~=true then
				if r[i]==s[i] then
					log = false
				end
			end
		else
			if r[i]==s[i] then
				log = false
			end
		end
	end
	if #r == 0 then
		log = true
	end
	if log == true then
		r = s
		while log==true do
			for i=1,#r do
				print(#r.." | "..i)
				script.Parent.ambience.SoundId = r[i]
				script.Parent.ambience.Loaded:Wait()
				script.Parent.ambience:Play()
				wait(script.Parent.ambience.TimeLength)
			end
		end
	end
end)

Biome change script:

wait(1)
game:GetService("RunService").RenderStepped:Connect(function()
	local e = game.Workspace.biomes:GetChildren()
	for i, v in pairs(e) do
		if v.Name=="biome" then
			if game.Players.LocalPlayer.Character.Head.Position.X>=v.Position.X-v.Size.X/2 then
				if game.Players.LocalPlayer.Character.Head.Position.X<=v.Position.X+v.Size.X/2 then
					if game.Players.LocalPlayer.Character.Head.Position.Z>=v.Position.Z-v.Size.Z/2 then
						if game.Players.LocalPlayer.Character.Head.Position.Z<=v.Position.Z+v.Size.Z/2 then
							if v.Position.Y>game.Players.LocalPlayer.Character.Head.Position.Y then
								if v.Parent.Parent~=game.Players.LocalPlayer.Character then
									if v.Value.Value==0 then
										script.Value.Value="Wasteland Edges"
										game.Players.LocalPlayer.PlayerGui.ambience.Playing = true
										game.Players.LocalPlayer.PlayerGui.ambience.Volume=.5
										script.id.Value = v.Value.Value
										game.Players.LocalPlayer.PlayerGui.sound.Event:Fire({"rbxassetid://3097850155"})
									end
									if v.Value.Value==1 then
										script.Value.Value="Sovirus Outskirts"
										game.Players.LocalPlayer.PlayerGui.ambience.Playing = true
										game.Players.LocalPlayer.PlayerGui.ambience.Volume=.5
										script.id.Value = v.Value.Value
										game.Players.LocalPlayer.PlayerGui.sound.Event:Fire({"rbxassetid://1988402059","rbxassetid://5965225694"})
									end
									if v.Value.Value==2 then
										script.Value.Value="Sovirus Farmlands"
										game.Players.LocalPlayer.PlayerGui.ambience.Playing = true
										game.Players.LocalPlayer.PlayerGui.ambience.Volume=.5
										script.id.Value = v.Value.Value
										game.Players.LocalPlayer.PlayerGui.sound.Event:Fire({"rbxassetid://931256455","rbxassetid://931254912","rbxassetid://935400460","rbxassetid://931260033"})
									end
									if v.Value.Value==3 then
										script.Value.Value="Sovirus Suburbs"
										game.Players.LocalPlayer.PlayerGui.ambience.Playing = true
										game.Players.LocalPlayer.PlayerGui.ambience.Volume=.5
										script.id.Value = v.Value.Value
										game.Players.LocalPlayer.PlayerGui.sound.Event:Fire({"rbxassetid://3182738096","rbxassetid://6062137050","rbxassetid://6062135904"})
									end
									if v.Value.Value==4 then
										script.Value.Value="Sovirus Citadel"
										game.Players.LocalPlayer.PlayerGui.ambience.Playing = true
										game.Players.LocalPlayer.PlayerGui.ambience.Volume=.5
										script.id.Value = v.Value.Value
										game.Players.LocalPlayer.PlayerGui.sound.Event:Fire({"rbxassetid://157172339"})
									end
								end
							end
						end
					end
				end
			end
		end
	end
end)

Drawing of what I want:


- Br, iSyriux

2 Likes

Hello,
Here is a drawing explaining further into detail my script.

Hello,
I have created a timeline graph diagram to show what I want.

Hello,
Why is it that no one ever replies to my posts? Is it because my problems are always too hard to solve?

1 Like

People may not be responding since the code isn’t that neat, almost nothing is referenced, and even the things that are referenced are given obscure names, like r and s. It’s fine for programmers who are just starting and making smaller scripts, but for something with this many lines, people just don’t want to read through all the children especially in your ‘Biome change script’.

4 Likes

Hello,
You can literally see the references if you look at the code. I posted two scripts and that’s all you need to know everything. FYI, “s” is just an array of strings which are the music playlist.
My code is neat and formatted, and I’ve already explained to my fullest extent what everything means.

Hello,
This right here:


Is this:

Hello,
Could anyone please help me?
@MrNicNac good samaritan?

So I’d like to start by stating what I assume to be the case, so that you can correct what I wrongly assume.

From what I currently understand, you’re trying to make a music player system that will play a certain playlist of music in an infinite loop when you’re in one biome, and another playlist in another. You’re having the code wait() for the length of the song, in seconds, before moving on to the next song. The songs forming a playlist are stored in integer values within a table. And finally, when you switch playlists, you want the table to swap out the old integers for the music in the playlist, and swap in the new integers for the new songs in the new playlist.

I have a few questions.

  1. How do you want the music (within a singular playlist) to play? Like, in what order?
  2. How is it you store the music for each playlist? Do you have them inside different folders somewhere?
  3. Are these all LocalScripts?
  4. Do you want the music to be different for each individual player depending on which biome they are in?
  5. How do you want the table to act? Do you want it to keep the old integers? Or is it okay to simply switch them out and not use the old ones, until they switch back to that biome?

EDIT:

Is the above code meant to check if the player is within the area of the biome? I assume that you created a giant with transparency of 1 (invisible) for each biome, and now are doing these calculations to check if the player is inside the part. If that is the case, there are much more efficient/more appealing looking methods to do this.

EDIT:

In the above code, what is v.Value.Value? Did you place some sort of IntValue/NumValue inside of the biome part?

Hello,
Thank you for your miraculous reply.
To answer your questions, firstly, v.Value.Value refers to an integer value in a biome part which defines the ID.


Yes, these are all localscripts.
I would like to play these in numerical order, for example, 1, 2, 3, 4, ect.
If you look at the biome detecting script, I have the music stored in arrays. There is no physical folder for it.
It is simply okay to switch them out and not use the old ones, because every wait(), the biome detecting script sends a bindableevent to the music playlist script. If the array sent is different from the previous one, it updates the previous array (r), and redoes the infinite playlist loop until the event array is different from the previous array.
The biome parts are just giant flat invisible parts in the sky.

Hello!

Your output says that it’s printing the count and currently playing index of the sound.
This is because ambience.Loaded:Wait() is waiting forever, because it is already loaded. You will need to check ambience.IsLoaded first.

if script.Parent.ambience.IsLoaded ~= true then
	script.Parent.ambience.Loaded:Wait()
end

Looking ahead, I see that the while log == true do loop will run forever, because log will never be set to false inside the loop. log is a local value, so each firing of the event gets its own log.
When you add that isLoaded check, I predict that the script will start changing the track while it is still playing (and to songs from previous playlists) after you change the biome.

In general, I would advise making the code clearer and easier to understand and less intimidating, by making the variables describe what they are and adding comments where that doesn’t cut it.
You could have named r playlistCurrent and s playlistNew, as it’s possible to lose track of what’s what.
In addition, it took me a moment to notice that the code connected to Event is actually responsible for checking whether the tables are equal. This wasn’t clear because the name log doesn’t describe what it is being used to track.

So, I’ve tried my best to redo this entire thing.

Biome Detector Script:

-- Services
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Variables
local biomes = game.Workspace.biomes:GetChildren()
local soundEvent = ReplicatedStorage:WaitForChild("Sound Event")
local currentBiomeID

RunService.RenderStepped:Connect(function()
    for i, v in pairs(biomes) do
        if v.Name == "biome" then
            -- Makes sure it's not doing the below code unnecessarily when the biome remains the same
            if biomeID == currentBiomeID then
                return
            end

            local h = game.Players.LocalPlayer.Character.playerHead.Position -- Player head position
            local bP = v.Position -- Biome Position
            local bS = v.Size -- Biome Size

            -- Checks if player is within the area of the biome
            if h.X >= bP.X - bP.X/2 and h.X <= bP.X + bS.X/2 and h.Z >= bP.Z - bS.Z/2 and h.Z <= bP.Z + bS/2 and bP.Y > h.Y then
                if biomeID >= 0 and biomeID <= 4 then
                    soundEvent:Fire(biomeID)
                    currentBiomeID = biomeID
                end
            end
        end
    end
end)

Music Player Script:

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

-- Variables
local playlists = {
    {ID = 0, "rbxassetid://3097850155"},
    {ID = 1, "rbxassetid://1988402059", "rbxassetid://5965225694"},
    {ID = 2, "rbxassetid://931256455","rbxassetid://931254912","rbxassetid://935400460","rbxassetid://931260033"},
    {ID = 3, "rbxassetid://3182738096","rbxassetid://6062137050","rbxassetid://6062135904"},
    {ID = 4, "rbxassetid://157172339"}
}

local soundEvent = ReplicatedStorage:WaitForChild("Sound Event")
local ambience = script.Parent.ambience
local currentPlaylist
local changed = false

soundEvent.OnEvent:Connect(function(BiomeID)
    for i, v in pairs(playlists) do
        if BiomeID == v.ID and currentPlaylist ~= BiomeID then -- If the BiomeID is found in the playlists table
            changed = true
            currentPlaylist = i
            changed = false
            break
        end
    end
end)

while changed == false do
    for i = 2, #playlists[currentPlaylist] do
        ambience.SoundId = playlists[currentPlaylist][i]
        if not ambience.IsLoaded then
            ambience.Loaded:Wait()
        end
        ambience:Play()
        wait(ambience.TimeLength)
    end
end

I’ve carried over, but optimized, much of what you were doing. Now, you’ll need to place a single RemoteEvent named “Sound Event” inside of ReplicatedStorage for the code to work. The sounds are now stored inside of the Music Player Script, and can have music added or removed from the single table as you want to, as long as it all stays in the same table “format.”

I realize there may be problems with this code, and so let me know if anything goes wrong. Also, feel free to ask questions.

Hello,

For @Eestlane771, although it is more practical to use the script you have provded, the wait function clearly works as the sound is not looped, and it plays the first sound in the table over and over again and waiting for the sound to finish.
For your insight on the log variable, I have moved it out of the event. Thank you for that.
For @MJTFreeTime, thank you for the valuebal feedback, but I have devised my own script that works like a charm.

local r = {}
local new = false

script.Event.Event:Connect(function(s)
	new = false
	if #r~=#s then
		new = true
	else
		for i=1,#r do
			if new==false then
				if r[i]==s[i] then
					new = false
				else
					new = true
				end
			end
		end
	end
	if new==true then
		r = s
		new = false
		repeat
			for i = 1,#r do
				script.Parent.ambience.SoundId = r[i]
				if script.Parent.ambience.IsLoaded==false then
					script.Parent.ambience.Loaded:Wait()
				end
				script.Parent.ambience:Play()
				wait(script.Parent.ambience.TimeLength)
			end
		until new==true
	end
end)

Hello,
My script appears to not be working.

What do you mean you “have devised a script that works like a charm?” You just said this:

I took your two scripts and rewrote them to be more readable and efficient with the purpose that you explained, as your scripts seem to have innefficient sections in them, and the code is uneccessarily long.

1 Like