This is my first tutorial, so if anything is wrong please correct me.
Today I’ll be going over how to make a simple music system, which loops through songs in a a table and plays them.
Preparing for the tutorial
We’re going to use 3 scripts for this tutorial, 2 module scripts, and 1 server script.
- First, create a Script inside ServerScriptService: Let’s call it “Music”.
- Create 2 ModuleScripts inside of your Music script that you’ve just created. Call one of the ModuleScripts Songs, and the other playSong
Great! Now you should have something like the following:
If not, make sure to match yours up with mine.
"Songs" ModuleScript
This script won’t do run code, or run functions, ect. Instead, it will return a table that has all the Song ID’s.
When you first open the Module, you will probably see the following:
local module = {}
return module
We don’t need this, so delete it. We need the script to just return a table, which is what the script was just doing, but we don’t need the top part.
Instead, now write
return {}
Easy! Let’s call this table “Returner”. That is what the original code was doing, but we’ve simplified it a lot. Now open the Returner table onto a new line, and we can add our ID’s. This can be done many ways, we’re going to do it like this:
[1] = {
Name = "", --// Name of the Song
Composer = "", --// Composer of the Song
ID = "", --// Song ID
}
You don’t need the Name and Composer variables, but we’re using them so we can show the client what song is playing.
Add that table into your Returner table, like this:
return {
[1] = {
Name = "",
Composer = "",
ID = "",
}
}
The [1]
doesn’t really matter, you can put anything there. It’s just so we have a Dictionary to return.
And you’re done with the Songs script! You can add as many songs as you would like, here’s an example of what I’m using in my game:
My Songs Module
return {
[1] = {
Name = "Catch My Vibe",
Composer = "APM Music",
ID = "rbxassetid://1843663426"
};
[2] = {
Name = "Clap for the Runner Up",
Composer = "APM Music",
ID = "rbxassetid://1843663202"
};
[3] = {
Name = "Dreamers Paradise",
Composer = "APM Music",
ID = "rbxassetid://1843689215"
};
[4] = {
Name = "Party Like We're Young Forever",
Composer = "APM Music",
ID = "rbxassetid://1843650802"
},
[5] = {
Name = "Set a High Bar",
Composer = "APM Music",
ID = "rbxassetid://1843662935"
},
[6] = {
Name = "So Much More",
Composer = "APM Music",
ID = "rbxassetid://1843652367"
};
[7] = {
Name = "This Time I Want it All",
Composer = "APM Music",
ID = "rbxassetid://1843651937"
};
[8] = {
Name = "Catch My Vibe",
Composer = "APM Music",
ID = "rbxassetid://1843663426"
}
}
"playSong" ModuleScript
First, delete everything inside of the Module.
This module is going to have 2 functions:
playNextSong()
getPlaying()
Let’s define some variables first, before writing these functions.
First we’re going to need the Songs to play, luckily we just wrote them! So we can get them by doing this:
local Songs = require(script.Parent.Songs)
require
basically just tells Roblox to give us that module and what it’s returning
Now we’re actually going to need basic module script stuff, create a variable like this:
local m = {}
Then finally, create another variable like this:
local currentSong = 1
playNextSong()
Now lets create the functions! We’ll start with playNextSong()
.
Tell the script you want to create a function, by writing the following:
function m:playNextSong()
end
This function requires no arguments, so we’ll leave the brackets empty.
Now lets code! All of the following code will be inside of the function.
Lets first change the current song, so the script doesn’t loop the same song.
if currentSong == #Songs then --// Checks if the current song is the last song we have
currentSong = 1 --// Loops back to the start
else --// If it's not the last song
currentSong += 1 --// Move onto the next song
end
Great, now let’s get our song.
local NextSong = Songs[currentSong]
Since Songs is a table, we can get the song using the square brackets [] and the index. Now that variable is one of our songs, like this:
{
Name = "",
Composer = "",
ID = "",
}
So for example, to get our Song name, we can do
NextSong.Name -- output: STRING
But we don’t need the name right now, we need the ID. Create a sound in workspace called CurrentSong. Now define it in your function:
local CurrentSongInst = game:GetService("Workspace").CurrentSong
Now we need to stop what ever is currently playing, set the new SongID, and then play it.
CurrentSongInst:Stop() -- Stops whatever song is current playing if any
CurrentSongInst.SoundId = NextSong.ID -- Sets new ID
CurrentSongInst:Play() -- Plays New Song
Cool! That’s basically it for our playNextSong function. This last step is optional, however you can fire an event to all players so the players have access to the next song table too!
game.ReplicatedStorage.Events.NewSong:FireAllClients(NextSong)
Please note that a folder named “Events” is needed with a child that is a RemoteEvent named NewSong
Final playNextSong() function
function m:playNextSong()
if currentSong == #Songs then
currentSong = 1
else
currentSong += 1
end
local NextSong = Songs[currentSong]
local CurrentSongInst = game:GetService("Workspace").CurrentSong
print(NextSong)
CurrentSongInst:Stop()
CurrentSongInst.SoundId = NextSong.ID
CurrentSongInst:Play()
game.ReplicatedStorage.Events.NewSong:FireAllClients(NextSong)
return NextSong
end
getPlaying()
This is simple
Create a new function called getPlaying()
function m:getPlaying()
end
Then inside the function, return what song is playing:
function m:getPlaying()
return Songs[currentSong]
end
And you’re done!
"Music" Script
First require both module scripts we just wrote.
local Songs = require(script.Songs)
local m = require(script.playSong)
You know what require does now, so I don’t need to explain it.
Now write the following under those two variables.
m:playRandomSong()
If you’ve done everything correctly, this should initialize everything and play a new song.
To loop play songs, you can detect when the song has ended, and run that function again.
game.Workspace.CurrentSong.Ended:Connect(function()
m:playNextSong()
end)
And you’re done!
Thanks for reading, I hope this helped you out in someway!
FAQ
- Why didn’t you just use
GetProductInfo()
to get the name and composer?
Because sometimes audio’s have really odd names, and about 80% of the time the person that posted the audio isn’t the composer.
this took like an hour to write due to how confusing raw formatting looks