Music Command Error

Issue: When you run “!skip”, the songs constantly are looping to change and skips multiple instead of one. I want to make it skip once.

Using :Stop() doesn’t help.

Command:

function onChatted(msg, speaker)
    local source = string.lower(speaker.Name)
    msg = string.lower(msg)
    if msg == "!skip" and speaker:GetRankInGroup(2321213) <13 then
        if Sound then
            Sound.TimePosition = Sound.TimeLength
            end
        end
    end
end

game.Players.PlayerAdded:Connect(function(player) 
    player.Chatted:connect(function(msg) onChatted(msg, player) end)
end)  

Song Playlist:

--//SONG LIST//--
local SongDatabase = {639750143, 279206904, 2164151618}

--//LOCALS//--
local SongName = game.ReplicatedStorage:WaitForChild("SongString")
local SongNumber = 0
local Sound = game.Workspace.GlobalMusic
local MPS = game:GetService("MarketplaceService")
local PlayerAddSongCheck = false
local RepStorage = game:GetService("ReplicatedStorage")

--//SCRIPT//--
while true do
	for i = 1, #SongDatabase do
		RepStorage.MusicEvents:WaitForChild("AddSongValue").OnServerEvent:Connect(function(player, SoundCheck)
			print(SoundCheck)
			table.insert(SongDatabase, i+1, SoundCheck)
		end)
		Sound.SoundId = "rbxassetid://"..tostring(SongDatabase[i])
		local SongInfo = MPS:GetProductInfo(tonumber(SongDatabase[i]))
		game:GetService("ReplicatedStorage").MusicEvents:WaitForChild("SongChange"):FireAllClients(SongInfo)
		--game:GetService("ReplicatedStorage").MusicEvents:WaitForChild("SongChange")
		wait(3)
		Sound:Play()
		Sound.Ended:Wait() 
	end
end	


1 Like

The Song Playlist worked fine before skip was ran.

The unfortunate part about Sounds in general is that the large majority of their properties do not replicate to the server, making it difficult to manipulate their position. The problem you are having (I believe) is that Sound.TimeLength is not correct on the server.

To prevent you from having to restructure the code you already have, I am going to suggest creating a BindableEvent (basically a custom event) that fires when your sound is either Stopped or has Ended.

Place this at the top of your code:

local CompletedBindable = Instance.new("BindableEvent")

Then, replace Sound.Ended:Wait() with

CompletedBindable.Event:Wait()

Finally, place this at the end of your code:

Sound.Ended:Connect(function() CompletedBindable:Fire() end)
Sound.Stopped:Connect(function() CompletedBindable:Fire() end)

In the command script, make sure to replace your TimePosition code with Sound:Stop()

1 Like

Ah, thank you for clearing some things up and apologize for the late reply.

When using Sound:Stop(), it replaces the .TimePosition to 0 and keeps the same SoundId where in I wanted it to go to the next song on the table.

1 Like

I believe this is what you mean by the script changes?

--//SONG LIST//--
local SongDatabase = {639750143, 279206904, 2164151618}

--//LOCALS//--
local SongName = game.ReplicatedStorage:WaitForChild("SongString")
local SongNumber = 0
local Sound = game.Workspace.GlobalMusic
local MPS = game:GetService("MarketplaceService")
local PlayerAddSongCheck = false
local RepStorage = game:GetService("ReplicatedStorage")
local CompletedBindable = Instance.new("BindableEvent")

--//SCRIPT//--
while true do
	for i = 1, #SongDatabase do
		RepStorage.MusicEvents:WaitForChild("AddSongValue").OnServerEvent:Connect(function(player, SoundCheck)
			print(SoundCheck)
			table.insert(SongDatabase, i+1, SoundCheck)
		end)
		Sound.SoundId = "rbxassetid://"..tostring(SongDatabase[i])
		local SongInfo = MPS:GetProductInfo(tonumber(SongDatabase[i]))
		game:GetService("ReplicatedStorage").MusicEvents:WaitForChild("SongChange"):FireAllClients(SongInfo)
		--game:GetService("ReplicatedStorage").MusicEvents:WaitForChild("SongChange")
		wait(3)
		Sound:Play()
		CompletedBindable.Event:Wait()
	end
end	

Sound.Ended:Connect(function() CompletedBindable:Fire() end)
Sound.Stopped:Connect(function() CompletedBindable:Fire() end)

local Sound = game.Workspace.GlobalMusic
function onChatted(msg, speaker)
    local source = string.lower(speaker.Name)
    msg = string.lower(msg)
    if msg == "!skip" and speaker:GetRankInGroup(2321213) <13 then
        if Sound then
            Sound:Stop()
            end
        end
    end

game.Players.PlayerAdded:Connect(function(player) 
    player.Chatted:connect(function(msg) onChatted(msg, player) end)
end)  

Ah wait, I forgot something.

Make sure you change this:

    if Sound then
        Sound:Stop()
        end
    end

to this:

    if Sound then
        CompletedBindable:Fire()
        end
    end

If the command is in a separate script from the main music loop, just parent the BindableEvent to ServerStorage and name it CompletedBindable, and then reference it like usual in the command script.

-- in music script
local CompletedBindable = Instance.new("BindableEvent")
CompletedBindable.Name = "CompletedBindable"
CompletedBindable.Parent = game:GetService("ServerStorage")


-- in command script
local CompletedBindable = game:GetService("ServerStorage"):WaitForChild("CompletedBindable")
2 Likes

Thank you :smile:

I believe you have to put the local CompletedBindable = game:GetService("ServerStorage"):WaitForChild("CompletedBindable") inside of the function for it to work.

        if Sound then
			local CompletedBindable = game:GetService("ServerStorage"):WaitForChild("CompletedBindable")
            CompletedBindable:Fire()
            end```
1 Like