Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

Remote event not firing in a while true do loop when more than 1 player joins?

Asked by 4 years ago
Edited 4 years ago

The script works fine for when the first player joins and starts the server (playing the music and showing the song name) but when another player joins, it just plays the music and doesn't show the song name for them until it switches to another song.

Script in Sound:

local Sound = Instance.new("Sound", game.Workspace)

Sound.Name = "SongAcreol2"

local musicList = require(game.ServerScriptService.SongList)

local Event = game.ReplicatedStorage.ApoxyzMusicChange

local musicName = musicList

local Activate = false

local keys = {}

for key, _ in pairs(musicList) do
    table.insert(keys, key)
end

game.Players.PlayerAdded:Connect(function(player)

    if Activate == false then

        Activate = true

        while true do

            local Change = game.ReplicatedStorage.ChangeSong

            Change.OnServerEvent:Connect(function(player, text)

                Sound:Stop()

                wait(0.5)

                Sound.SoundId = "rbxassetid://"..text

                local musicNameInfo = game:GetService("MarketplaceService"):GetProductInfo(text).Name
                Event:FireAllClients(musicNameInfo)

                Sound:Play()

                Sound.Ended:Wait()

            end)

            local Skip = game.ReplicatedStorage.SkipSong

            Skip.OnServerEvent:Connect(function()

                Sound:Stop()

                wait(0.5)

                local randomKey = keys[math.random(#keys)]

                Sound.SoundId = "rbxassetid://"..randomKey

                musicName = musicList[randomKey]
                Event:FireAllClients(musicName)

                Sound:Play()

                Sound.Ended:Wait()

            end)

            wait(0.5)

            local randomKey = keys[math.random(#keys)]

            Sound.SoundId = "rbxassetid://"..randomKey

            Sound:Play()

            musicName = musicList[randomKey]
            Event:FireAllClients(musicName)

            Sound.Ended:Wait()

        end

    end

    Event:FireClient(player, musicName)

end)

Local Script in TextLabel:

local Event = game.ReplicatedStorage.ApoxyzMusicChange

Event.OnClientEvent:Connect(function(musicName)
    if musicName then
        script.Parent.Text = musicName
    end
end)

2 answers

Log in to vote
0
Answered by
Torren_Mr 334 Moderation Voter
4 years ago

You forgot to make the Activate value false at the end.

Try using this code:

local Event = game.ReplicatedStorage.ApoxyzMusicChange

local Activate = false

game.Players.PlayerAdded:Connect(function()

    if Activate == false then

        Activate = true

        while true do

            wait(0.5)

            local randomKey = keys[math.random(#keys)]

            script.Parent.SoundId = "rbxassetid://"..randomKey

            local musicName = musicList[randomKey]
            Event:FireAllClients(musicName)

            script.Parent:Play()

            script.Parent.Ended:Wait()
            Activate = false --Added the line. 
        end
        --Put the line I added here if it doesn't work.
    end
end)

If the script above doesn't work in the way you wanted it to, try moving the line I added 2 lines below.

Ad
Log in to vote
0
Answered by 4 years ago
Edited 4 years ago

Hey bud, I was helping you out with your other post on this. All you need to do to fix this is add one line of code and change the order around a little. Here is your updated code:

local Event = game.ReplicatedStorage.ApoxyzMusicChange
local musicName = "" -- moved the scope outside so it can be used outside of the while loop
local Activate = false

game.Players.PlayerAdded:Connect(function(player) --Added player to capture the newly joined player

    if Activate == false then

        Activate = true

        while true do

            wait(0.5)

            local randomKey = keys[math.random(#keys)]

            script.Parent.SoundId = "rbxassetid://"..randomKey

            musicName = musicList[randomKey] -- removed local from in front of here
            Event:FireAllClients(musicName)

            script.Parent:Play()

            script.Parent.Ended:Wait()

        end
    end
    Event:FireClient(player, musicName) -- This will only send musicName to players that join. FireClient must always send the individual player, but the local script does not need to include the player, so don't change your local script.
end)

Also, I remember your other post on this, so don't change Activate back to false. You wanted the while loop to run only once as I remember. I hope this helps out! If it doesn't, please keep this post opened and add a comment under my post. I check my answers for feedback regularly.

I also noticed that you structured your code differently than what I did to prevent the Studio bug. Unless they fixed this (it's been around for a long time, so doubtful) you will definitely experience the bug as your game grows. It's ultimately your choice, but I promise it will save you some headache down the line.

[EDIT] The second problem probably should've been in another post since it was new problems based off of your changes, but I fixed it for you anyway. All I did was move some things around a little bit, you were definitely on the right track.

Here is the updated script:

local Sound = Instance.new("Sound", game.Workspace)
Sound.Name = "SongAcreol2"
local musicList = { --replace this with your module script
    ["356718047"] = "N'to Trauma",
    ["372492410"] = "Tell Me Why",
    ["2468961271"] = "Mine The Diamond"
    }
local Event = game.ReplicatedStorage.ApoxyzMusicChange
local musicName --If you have a huge song list, then it's better not to have the same information in two places. No need to set this to any value.
local Activate = false
local keys = {} 
local Change = game.ReplicatedStorage.ChangeSong
local Skip = game.ReplicatedStorage.SkipSong

for key, _ in pairs(musicList) do
    table.insert(keys, key)
end

local function Music() --Originally made this function because I thought I would need to kill multiple threads
    while true do
        wait(0.5)
        local randomKey = keys[math.random(#keys)]
        Sound.SoundId = "rbxassetid://"..randomKey
        Sound:Play()
        musicName = musicList[randomKey]
        Event:FireAllClients(musicName)
        Sound.Ended:Wait()
    end
end
game.Players.PlayerAdded:Connect(function(player)
    if Activate == false then
        Activate = true
        Music() -- Just calling a function, you can still think of the while loop as being in here
    end
    Event:FireClient(player, musicName)
end)

--[[ Commented out since I'm not really sure the difference between the skip and Change events
Change.OnServerEvent:Connect(function(player, text)
    Sound:Stop()
    wait(0.5)
    Sound.SoundId = "rbxassetid://"..text
    local musicNameInfo = game:GetService("MarketplaceService"):GetProductInfo(text).Name
    Event:FireAllClients(musicNameInfo)
    Sound:Play()
    Sound.Ended:Wait()
end)
--]]
Skip.OnServerEvent:Connect(function()
    Sound:Stop()
    wait(0.5)
    local randomKey = keys[math.random(#keys)]
    Sound.SoundId = "rbxassetid://"..randomKey
    musicName = musicList[randomKey]
    Event:FireAllClients(musicName)
    Sound:Play()
    Sound.Ended:Wait()

end)

A good rule of thumb is don't embed event-driven functions within one another. If you need several functions to use the same variables, then increase the scope of the variables to the highest scope. Be careful when doing this though, you'll need to account for the different values of the variable in the different functions.

I tested it as well in Studio for single and multiple players with the skip button, without the skip button, letting the song finish, and combinations of the three.

0
Seems to be working great, thank you, this has been aggravating me for awhile. I deleted the other post because I didn't realize you'd come back to check the comment I posted. This code is supposed to run constantly, not just once but it still works and the song changes and shows the name for everyone even when they join. Thank you again! Asynchronize 16 — 4y
0
Any time, glad to help! SteelMettle1 394 — 4y
0
Yeah it broke again, it works great when you first join but when the song switches it just breaks. I'm getting sick of this, do you have any suggestions? I edited the post and made it the full script. Asynchronize 16 — 4y
0
I think I've fixed your changes. SteelMettle1 394 — 4y
View all comments (5 more)
0
For some reason it still isn't working, it's being really weird but I don't want to bother you again with this. I've just been really busy with work so I can't work on this that much as I want too. It's been making me mad lol. I'll probably work on it later on with some of yours tips to help me. Thanks for everything. Asynchronize 16 — 4y
0
It sometimes stops playing for the 2nd half of the song, after a switch it will sometimes start a song already half way through, sometimes just switches and shows the song name but doesn't play the song. Not sure if you know what could be causing any of this? Asynchronize 16 — 4y
0
Your first problem may be from Roblox only allowing 1 minute 20 second audio files. So if you have a song that's 3 minutes long, you'll need at least 2 audio files (you'll still lose the last 20 seconds of the song though unless you play a third audio file). SteelMettle1 394 — 4y
0
As far as the second problem, I'm honestly not sure. I tested the code given in every way I could think of and it worked just fine. This tells me there's something else in your code that I don't have, unless of course it's because of the 1 minute 20 second problem. SteelMettle1 394 — 4y
0
I'm not too sure either man, thanks for your help though. Asynchronize 16 — 4y

Answer this question