I’ve seen a bunch of resources for this online, but what I want is different. Most resources just play a random music ID, and some will randomly play everything without repeating.
The randomizer I’m making does two things: It plays all of the music before starting over, and when it starts over the last song played on the old shuffle won’t be the first song played on the new shuffle, ie: First random shuffle: 2, 1, 3 Second random shuffle: 3, 1, 2 ← This is not okay because 3 had just played
Here’s the script, it is random, but sometimes plays repeats which means the part about the previous song is broken.
local Songs = {
"rbxassetid://5869422451",
"rbxassetid://3060494212",
"rbxassetid://17755696142"
}
local AlreadyPlayed = {}
local Sound = script.Parent.Sound
local PreviousSong
while wait() do
if #AlreadyPlayed == #Songs then
table.clear(AlreadyPlayed)
end
local RandomID = Songs[math.random(1,#Songs)]
if table.find(AlreadyPlayed, RandomID) then
repeat
wait()
RandomID = Songs[math.random(1,#Songs)]
until
print("found")
else
if tostring(RandomID == PreviousSong) then repeat wait() RandomID = Songs[math.random(1,#Songs)] until tostring(RandomID ~= PreviousSong)
Sound.SoundId = RandomID
Sound:Play()
Sound.Ended:Wait()
PreviousSong = RandomID
end
end
end
On a side question, instead of doing this to make a table, can I just locate a folder with the song instances inside and rip the song ID’s from there?
local Songs = {
"rbxassetid://5869422451",
"rbxassetid://3060494212",
"rbxassetid://17755696142"
}
local Sound = script.Parent.Sound;
local Songs = {
"rbxassetid://5869422451",
"rbxassetid://3060494212",
"rbxassetid://17755696142"
};
local function Shuffle(t)
local s = {};
for i = 1, #t do
s[i] = t[i];
end
for i = #t, 2, -1 do
local j = math.random(i);
s[i], s[j] = s[j], s[i];
end
return s;
end
local lastSong = Songs[1];
local Queue;
while wait() do
repeat
Queue = Shuffle(Songs);
until Queue[1] ~= lastSong;
lastSong = Queue[#Queue];
for _,SongID in ipairs(Queue) do
Sound.SoundId = SongID;
Sound:Play();
Sound.Ended:Wait();
end
end
Something like this?
See @doctorpepper126’s response for how to pull the IDs from a folder of Instances
local RANDOM_OBJECT = Random.new()
local songs = {}
local alreadyPlayed = {}
local prevSong
local folder = script.Songs
local sound = script.Parent.Sound
for _, sound: Sound in pairs(folder:GetChildren()) do
table.insert(songs, sound.SoundId)
end
while (true) do
while (#songs > 0) do
local randomSong
repeat
randomSong = songs[RANDOM_OBJECT:NextInteger(1, #songs)]
until (randomSong ~= prevSong)
table.insert(alreadyPlayed, randomSong)
table.remove(songs, table.find(songs, randomSong))
prevSong = randomSong
sound.SoundId = randomSong
if (not sound.IsLoaded) then
sound.Loaded:Wait()
end
sound:Play()
sound.Ended:Wait()
end
songs = table.clone(alreadyPlayed)
table.clear(alreadyPlayed)
end
So, this assumes you’ve got a folder inside of the script called Songs with Sound objects in it. It’ll take all SoundIds of those sounds and place them into a table, as you wanted. It’ll also ensure that the last song in a shuffle is not played first in the very next shuffle. If you want a more thorough explanation as to what’s going on here, don’t hesitate to ask!
A couple of side notes, though.
The Random object is newer and you shouldn’t use math.random. I don’t know whether Roblox plans to deprecate math.random(meaning they’d no longer support it if it were to stop working), but they tend to do that to features that get a newer counterpart. It has more functionality than math.random and you should get into the habit of using it. Here’s the documentation page for it.
You also should not use wait(), as it’s deprecated, and you instead should be using task.wait().
I’ve used lastSong as a variable to define the last song that played in each queue. I’ve assigned it to Songs[1] for the first iteration (just so it’s not empty), but every time a new Queue is made it replaces this with the last song in that Queue: lastSong = Queue[#Queue]
On each iteration, it will shuffle the song list over-and-over again until the first song in the Queue (Queue[1]) is not the same as lastSong. At which point the repeat ... until ... breaks.
Then the for _,SongID is just looping through the Queue in order to play each song.