Scripting - Making a Music Queue

An updated version of this system has been published: Music Player Tutorial - Resources / Community Tutorials - DevForum | Roblox

39 Likes

Nice tutorial!

Just a quick point: Unfortunately, Roblox removed proper tailcalling from Lua. Because of this, you will end up getting a stackoverflow error eventually after recursively calling playSong too much.

This can be fixed easily in two different ways:

  1. Hook up playSong to a BindableEvent and fire the event in order to call the function. This will effectively do the same thing that a tailcall tries to accomplish.
  2. Just use a while loop and continuously loop through all the songs.
16 Likes

Oh really? I never knew that. I’ve used this code in many ways and that has never happened to me. Thanks though! I’ll edit the post and include your reply in there. :slight_smile:

4 Likes

There, I edited my post. :smiley: Thanks for the suggestion. I really appreciate the feedback.

4 Likes

You could use a table for song list instead of intvalues in a folder and use getproductinfo for the name of the song.

nice tutorial :slight_smile:

2 Likes

Yes I completely agree. However, it’s also a good idea to leave the name of the songs that can be displayed in-game to the game editor. That way, it doesn’t include things like “[200+ FAVORITES!]” or anything like that. Thanks for the feedback though.

1 Like

I just want to say brilliant work. Love the way it’s made.

1 Like

Thanks! Love your feedback. :heart:

Lovely! I have to questions. First off, is this music queue local? Does everyone hear the same song at the same time? My second question is, are you going to add how to request/skip a song?

1 Like

For the first question, yes it is. Since we’re storing the sound object in the workspace and the scripts in the server, it should be synced across clients. Sometimes, it may be a few seconds off, but it fixes itself when a new song plays. For the second question, I don’t really know. I might add this functionality to the tutorial later on.

Thanks for the reply. :stuck_out_tongue:

1 Like

Thank you, this is going to help me so much! Adding in a skip command would be so helpful!

1 Like

I added skip command functionality! You can check it out. :smiley:

1 Like

Awesome! Great feature! Now we just need a pause command! :slight_smile:

1 Like

Use SoundService instead of putting the sounds in Workspace, as SoundService is meant for sounds.

1 Like

Well, I made a Music System, that’s open-sourced.
But do you want to add a Blacklisted Music, just incase.

Great tutorial!

However, I have a concern with your implementation of those bindable events. In the line below:

if #queue == 0 then script.addSongs:Fire() end

could you not run into possible undefined behavior? The way the code is set-up, the addSongs event will fire as the rest of that current playSong event thread is running. I feel like potentially you could be indexing the queue before it has been refilled. There may be something I’m missing though.

A possible solution to this could be to yield the playSong thread until addSongs has finished executing.

I’m interested to hear your thoughts on this. :slightly_smiling_face:

2 Likes

Thanks for the suggestion. I don’t really mess around with sound objects a lot. I’ll edit my post. :smiley:

1 Like

ROBLOX automatically yields when you fire events I believe. The code below that if statement will run after the function has finished running its code, I’m not entirely sure. Thanks for the reply.

EDIT: I just found out in the developer page that it doesn’t. Thanks for noticing that! A possible way to fix this is to use a BindableFunction instead and simply return any value when the code is done. I do know that BindableFunctions do yield as ROBLOX waits for them to return a value.

It’s if player:GetRankInGroup(000000) >= 5

It doesn’t matter. That’s up to the user writing the script to do. It doesn’t have to be >= 5