0
votes

So here's the deal, I'm working on a game that is similar to a murder mystery and this part of the system is to start the round and show the players their roles and then the map. Except it used to work and I didn't knowingly do anything to the scripts that would affect it so the game crashes when this part is carried out. All I know is it starts to display the role and often does, it also plays the sound and displays the correct description, however it crashes just after that and sometimes just before the role is revealed. I've attached the function that runs when the RoundStarter event is fired to the client.

The server doesn't crash but, all of the clients do but not all at the exact same moment in time; Previously when there has been errors, I've been able to identify an error message but none of the clients throw any clear issues.

In testing mode in Roblox Studio, they freeze just after the drum roll sound effect as the role is displayed, however no errors and the server seems to be acting normally. Near enough the same thing happens when ran in Roblox.

Clientside script

    ReplicatedStorage.Players.Events.RoundStarter.OnClientEvent:Connect(function(Role,Map)
    local player = game.Players.LocalPlayer

    player.CameraMode = Enum.CameraMode.LockFirstPerson
    script.Parent.RoundGui.RoundEnd.Visible = false
    game.Players.LocalPlayer.NameDisplayDistance = 0
    CURRENTROLE = Role
    CURRENTMAP = Map
    script.Parent.RoundGui.Enabled = true

    script.Parent.RoundGui.RoundStarter.Visible = true
    script.Parent.RoundGui.RoundStarter.Fader.Visible = true
    script.Parent.RoundGui.RoundStarter.Fader.BackgroundTransparency = 0
    script.Parent.RoundGui.RoundStarter.RoleDescription.Visible = false
    script.Parent.RoundGui.RoundStarter.RoleName.Visible = false
    script.Parent.RoundGui.RoundStarter.Text.Visible = true
    local transp = 0
    for i = 1,50,1 do
        transp += 0.05
        script.Parent.RoundGui.RoundStarter.Fader.BackgroundTransparency = transp
        wait(.1)
    end 
    script.Parent.RoundGui.RoundStarter.DR:Play()
    script.Parent.RoundGui.RoundStarter.RoleName.Visible = true
    script.Parent.RoundGui.RoundStarter.RoleName.Text = Role
    script.Parent.RoundGui.RoundStarter.RoleDescription.Visible = true

    if Role == "Civilian" then
        script.Parent.RoundGui.RoundStarter.RoleDescription.Text = "Your Job is to help the Inspector find the shadow... Work to figure them out and stop them before it's too late! Don't tell anyone your Role!"
        script.Parent.RoundGui.RoundStarter.RoleName.TextColor3 = Color3.fromRGB(0, 255, 17)
    elseif Role == "Shadow" then
        script.Parent.RoundGui.RoundStarter.RoleName.TextColor3 = Color3.fromRGB(255, 0, 0)
        script.Parent.RoundGui.RoundStarter.RoleDescription.Text = "It's time... Infiltrate the crowd, gain their trust and kill the inspector to win! By killing another player, You can take on their form and blend in with the Civilians. More help will be on left of the screen. Don't tell anyone your Role!"        
    elseif Role == "Inspector"  then
        script.Parent.RoundGui.RoundStarter.RoleName.TextColor3 = Color3.fromRGB(0, 38, 255)
        script.Parent.RoundGui.RoundStarter.RoleDescription.Text = "You are nominated to fight the Shadow and eliminate them. You must work with the Civilians to figure out who the Shadow is, if you die you lose. Don't tell anyone your Role!"      
    end
    wait(10)
    script.Parent.RoundGui.RoundStarterMap.Visible = true
    script.Parent.RoundGui.RoundStarterMap.Fader.Visible = true
    script.Parent.RoundGui.RoundStarterMap.MapDescription.Visible = false
    script.Parent.RoundGui.RoundStarterMap.MapName.Visible = false

    local transp = 0
    for i = 1,50,1 do
        transp += 0.05
        script.Parent.RoundGui.RoundStarterMap.Fader.BackgroundTransparency = transp
        wait(.1)
    end
    script.Parent.RoundGui.RoundStarterMap.MapName.Visible = true
    script.Parent.RoundGui.RoundStarterMap.MapName.Text = Map
    script.Parent.RoundGui.RoundStarter.Dun:Play()

    if Map == "The Office" then
        script.Parent.RoundGui.RoundStarterMap.MapDescription.Text = "A classic map based in an Office building, in a power cut, near midnight. With an outdoor and Indoor area to explore, will you survive?"

    elseif Map =="The Village" then

        script.Parent.RoundGui.RoundStarterMap.MapDescription.Text = "The original map based in a small villiage with numerous buildings and areas to explore."     

    end
    script.Parent.RoundGui.RoundStarterMap.MapDescription.Visible = true
    wait(10)
    script.Parent.RoundGui.RoundEnd.Visible = false
    script.Parent.RoundGui.RoundStarterMap.Visible = false
    script.Parent.RoundGui.RoundStarter.Visible = false
end)
--This is the next function in the code that should be executed at a similar time to the above one (It should have an InMap value of true.
ReplicatedStorage.Players:WaitForChild(player.Name).InMap.Changed:Connect(function()
    data = game.ReplicatedStorage.GetPlayerDataCS:InvokeServer()
    if ReplicatedStorage.Players[player.Name].InMap.Value == false then

        --StartGUI:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList, true)
        player.CameraMode = Enum.CameraMode.Classic
        --StartGUI:SetCoreGuiEnabled(Enum.CoreGuiType.Chat,true)
        script.Parent.LobbyGui.Enabled = true
        script.Parent.RoundGui.Enabled = false
        wait()

    else

        if CURRENTROLE == "Shadow" then
            script.Parent.RoundGui.ShadowPanel.Visible = true
            script.Parent.RoundGui.CivPanel.Visible = false
            script.Parent.RoundGui.InsPanel.Visible = false
            
            if data then
                if data.EquippedAbility ~="None" and  data.EquippedAbility ~="" then
                    script.Parent.RoundGui.ShadowPanel[data.EquippedAbility].Visible = true
                end 
            end
        elseif CURRENTROLE == "Inspector" then
            script.Parent.RoundGui.ShadowPanel.Visible = false
            script.Parent.RoundGui.CivPanel.Visible = false
            script.Parent.RoundGui.InsPanel.Visible = true      
        else
            script.Parent.RoundGui.ShadowPanel.Visible = false
            script.Parent.RoundGui.CivPanel.Visible = true
            script.Parent.RoundGui.InsPanel.Visible = false     
        end

        --StartGUI:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList, false)
        --StartGUI:SetCoreGuiEnabled(Enum.CoreGuiType.Chat,true)
        script.Parent.LobbyGui.Enabled = false
        script.Parent.RoundGui.Enabled = true
        wait()
    end 
end)

Here's also the script on the server that should be near the event.

local replicatedstor = game:GetService("ReplicatedStorage")
local playersinthemap = {}
local playersinserver = game.Players:GetPlayers()   
local maplist = {"The Village"}
local TESTINGMODE = false
local goodwin = false
local COUNT = 0
local deadpool = {}
local DataStoreService = game:GetService("DataStoreService")
local Datastore = DataStoreService:GetDataStore("THE_MASQUERADE_TEST2")
function UpdateStatuses(Playerr,NewStatus)

    local c = Playerr
    



    if NewStatus == "Lobby" or NewStatus == "AFK" then
        if game.ReplicatedStorage.Players[c.Name].Status.Value == "Shadow" then
            script.RoundsInProgress.Value = false
            goodwin = true
        elseif game.ReplicatedStorage.Players[c.Name].Status.Value == "Inspector" then
            script.RoundsInProgress.Value = false
            goodwin = false 
        end

        game.ReplicatedStorage.Players[c.Name].InMap.Value = false
        if table.find(playersinthemap,c,1)~= nil then
            local index = table.find(playersinthemap,c,1)
            table.remove(playersinthemap,index)

        end



    end
    game.ReplicatedStorage.Players[c.Name].Status.Value = NewStatus
    if #playersinthemap <= 2 and script.RoundsInProgress.Value == true then
        script.RoundsInProgress.Value = false
        goodwin = false         
    end
end



game.ReplicatedStorage.Players.Events.SetStatus.OnServerEvent:Connect(function(Player,Status)
    if Status ~= nil then

        UpdateStatuses(Player,Status)

    else
        print ("Tried to change status of Player but the given status was nil.")
    end
end)

while true do   

    
    while script.RoundsRunning.Value == true do
        game.ReplicatedStorage.Players.Events.Notify:FireAllClients("Intermission...","L",false)
        --game.ReplicatedStorage.Game.Intermission:Fire(30)
        --game.ReplicatedStorage.Game.Intermission.Event:Wait()
        wait(35)
        game.Workspace.Lobby.DATABOARD.SurfaceGui.Frame.Title.Text = "Round starting soon..."
        --game.ReplicatedStorage.Players.Events.Notify:FireAllClients("Round starting soon...","L",true)
        --game.Workspace.Lobby.DATABOARD.SurfaceGui.Frame.Time.Text = ""
        if not game.Workspace.Map then
            playersinthemap = {}
            local Mapfolder = Instance.new("Folder",game.Workspace)
            Mapfolder.Name = "Map"
        end

        playersinserver = game.Players:GetPlayers()

        wait(10)
        playersinserver = game.Players:GetPlayers() 
        if #playersinserver >= 4 or (TESTINGMODE == true and #playersinserver >= 3) then
            game.Workspace.Lobby.DATABOARD.SurfaceGui.Frame.Title.Text = "Round loading..."
            game.ReplicatedStorage.Players.Events.Notify:FireAllClients("Loading the round now...","L",false)
            playersinserver = game.Players:GetPlayers() 
            local chosenMapIndex = math.random(#maplist)
            local chosenMapName = maplist[chosenMapIndex]
            local chosenShadowIndex = math.random(#playersinserver)
            local chosenShadow = playersinserver[chosenShadowIndex]
            local chosenInspectorIndex = math.random(#playersinserver)  
            local chosenInspector = playersinserver[chosenInspectorIndex]
            while chosenInspector == chosenShadow do
                chosenInspectorIndex = math.random(#playersinserver)    
                chosenInspector = playersinserver[chosenInspectorIndex]
            end
            local playernumber = playersinserver
            COUNT = 0
            while COUNT ~= #playersinserver do
                COUNT += 1
                local playername = playersinserver[COUNT].Name
                print (playersinserver)
                print ("Player trying to send role data:"..playername)
                if playersinserver[COUNT] == chosenShadow then
                    game.ReplicatedStorage.Players.Events.RoundStarter:FireClient(playersinserver[COUNT],"Shadow",chosenMapName)
                    game.ReplicatedStorage.Players[playersinserver[COUNT].Name].Status.Value = "Shadow"
                    --temp = game.ReplicatedStorage.ReadStatus:Invoke(playername,"Shadow")
                elseif playersinserver[COUNT] == chosenInspector then
                    game.ReplicatedStorage.Players.Events.RoundStarter:FireClient(playersinserver[COUNT],"Inspector",chosenMapName)
                    game.ReplicatedStorage.Players[playersinserver[COUNT].Name].Status.Value = "Inspector"

                    --temp = game.ReplicatedStorage.ReadStatus:Invoke(playername,"Inspector")

                else
                    game.ReplicatedStorage.Players.Events.RoundStarter:FireClient(playersinserver[COUNT],"Civilian",chosenMapName)
                    game.ReplicatedStorage.Players[playersinserver[COUNT].Name].Status.Value = "Civilian"
                    --temp = game.ReplicatedStorage.ReadStatus:Invoke(playername,"Civilian")

                end
            end         

            wait()
            local MapInServerStorage = game.ServerStorage.Maps:FindFirstChild(chosenMapName)
            local LoadedMap = MapInServerStorage:Clone()
            LoadedMap.Parent = game.Workspace.Map
            local spawns = {}
            for i,c in pairs(LoadedMap:GetDescendants()) do

                if c.Name == "Spawn" then
                    table.insert(spawns,1,c)
                end
            end
            COUNT = 0
            local i = COUNT
            while COUNT ~= #playersinserver do
                COUNT += 1
                print ("Setting Character locations. Loop:"..COUNT)
                local spawnlistindex = math.random(#spawns)
                playersinserver[COUNT].Character:SetPrimaryPartCFrame(spawns[spawnlistindex].CFrame)
                --playersinserver[COUNT].Character:SetPrimaryPartCFrame(LoadedMap.Spawns.Spawn.CFrame)
                table.insert(playersinthemap,1,playersinserver[COUNT])
                playersinserver[COUNT].NameDisplayDistance = 0
                game.ReplicatedStorage.Players:FindFirstChild(playersinserver[COUNT].Name).InMap.Value = true
                if playersinserver[COUNT] == chosenInspector then
                    local data = game.ReplicatedStorage.GetPlayerData:Invoke(chosenInspector)
                    
                    Pistl = game.ServerStorage.Guns[data.EquippedSkin]:Clone()
                    Pistl.Parent = playersinserver[COUNT].Backpack
                end
            end
            print ("Round starting...")
            --This is then followed by the rest of the round system which should be working but I have cut it to try to shorten the amount of reading but can be supplied if needed. It is closed correctly.

I've tried to keep the code to a minimum however it could be anywhere and as there are no obvious script related error codes, I'm requesting some assistance in some way.

There are other things that may have caused it but this is becoming a real issue, especially since it used to work, and I've included all of the likely suspects but I'm happy to give anything else if these aren't incorrect in anyway.

If you wish to see what happens yourself, you'll need either 4 Roblox Accounts or 3 extra friends. Here's the game on Roblox: The Masquerade

If anything else is needed, feel free to let me know and thanks for reading and any potential help. (Just so you know, I have done a lot of research on all of the functions and things I'm using but I can't find any issues, it just freezes & crashes).

The only error codes I've got are:

 Start Process Exception...
 Uploading crash analytics 
 Done uploading crash analytics
1

1 Answers

0
votes

There are some random wait() statements without any arguments, which shouldn't be in your code anyway. This may very well hang up the server / client.

Also, you appear to have a few while loops which do not have any wait()'s. That's a pretty common problem which stalls the client executing the script. Try adding at least wait(0.01) to the end of each while true loop that doesn't have it already.

There might be some occurences of this in the client as well (like that one lonely wait() with no parameters), but here's a modified version of your server script:

while true do   


while script.RoundsRunning.Value == true do
    game.ReplicatedStorage.Players.Events.Notify:FireAllClients("Intermission...","L",false)
    --game.ReplicatedStorage.Game.Intermission:Fire(30)
    --game.ReplicatedStorage.Game.Intermission.Event:Wait()
    wait(35)
    game.Workspace.Lobby.DATABOARD.SurfaceGui.Frame.Title.Text = "Round starting soon..."
    --game.ReplicatedStorage.Players.Events.Notify:FireAllClients("Round starting soon...","L",true)
    --game.Workspace.Lobby.DATABOARD.SurfaceGui.Frame.Time.Text = ""
    if not game.Workspace.Map then
        playersinthemap = {}
        local Mapfolder = Instance.new("Folder",game.Workspace)
        Mapfolder.Name = "Map"
    end

    playersinserver = game.Players:GetPlayers()

    wait(10)
    playersinserver = game.Players:GetPlayers() 
    if #playersinserver >= 4 or (TESTINGMODE == true and #playersinserver >= 3) then
        game.Workspace.Lobby.DATABOARD.SurfaceGui.Frame.Title.Text = "Round loading..."
        game.ReplicatedStorage.Players.Events.Notify:FireAllClients("Loading the round now...","L",false)
        playersinserver = game.Players:GetPlayers() 
        local chosenMapIndex = math.random(#maplist)
        local chosenMapName = maplist[chosenMapIndex]
        local chosenShadowIndex = math.random(#playersinserver)
        local chosenShadow = playersinserver[chosenShadowIndex]
        local chosenInspectorIndex = math.random(#playersinserver)  
        local chosenInspector = playersinserver[chosenInspectorIndex]
        while chosenInspector == chosenShadow do
            chosenInspectorIndex = math.random(#playersinserver)    
            chosenInspector = playersinserver[chosenInspectorIndex]
        end
        local playernumber = playersinserver
        COUNT = 0
        while COUNT ~= #playersinserver do
            COUNT += 1
            local playername = playersinserver[COUNT].Name
            print (playersinserver)
            print ("Player trying to send role data:"..playername)
            if playersinserver[COUNT] == chosenShadow then
                game.ReplicatedStorage.Players.Events.RoundStarter:FireClient(playersinserver[COUNT],"Shadow",chosenMapName)
                game.ReplicatedStorage.Players[playersinserver[COUNT].Name].Status.Value = "Shadow"
                --temp = game.ReplicatedStorage.ReadStatus:Invoke(playername,"Shadow")
            elseif playersinserver[COUNT] == chosenInspector then
                game.ReplicatedStorage.Players.Events.RoundStarter:FireClient(playersinserver[COUNT],"Inspector",chosenMapName)
                game.ReplicatedStorage.Players[playersinserver[COUNT].Name].Status.Value = "Inspector"

                --temp = game.ReplicatedStorage.ReadStatus:Invoke(playername,"Inspector")

            else
                game.ReplicatedStorage.Players.Events.RoundStarter:FireClient(playersinserver[COUNT],"Civilian",chosenMapName)
                game.ReplicatedStorage.Players[playersinserver[COUNT].Name].Status.Value = "Civilian"
                --temp = game.ReplicatedStorage.ReadStatus:Invoke(playername,"Civilian")

            end
        end         

        -- wait()     useless wait
        local MapInServerStorage = game.ServerStorage.Maps:FindFirstChild(chosenMapName)
        local LoadedMap = MapInServerStorage:Clone()
        LoadedMap.Parent = game.Workspace.Map
        local spawns = {}
        for i,c in pairs(LoadedMap:GetDescendants()) do

            if c.Name == "Spawn" then
                table.insert(spawns,1,c)
            end
        end
        COUNT = 0
        local i = COUNT
        while COUNT ~= #playersinserver do
            COUNT += 1
            print ("Setting Character locations. Loop:"..COUNT)
            local spawnlistindex = math.random(#spawns)
            playersinserver[COUNT].Character:SetPrimaryPartCFrame(spawns[spawnlistindex].CFrame)
            --playersinserver[COUNT].Character:SetPrimaryPartCFrame(LoadedMap.Spawns.Spawn.CFrame)
            table.insert(playersinthemap,1,playersinserver[COUNT])
            playersinserver[COUNT].NameDisplayDistance = 0
            game.ReplicatedStorage.Players:FindFirstChild(playersinserver[COUNT].Name).InMap.Value = true
            if playersinserver[COUNT] == chosenInspector then
                local data = game.ReplicatedStorage.GetPlayerData:Invoke(chosenInspector)
                
                Pistl = game.ServerStorage.Guns[data.EquippedSkin]:Clone()
                Pistl.Parent = playersinserver[COUNT].Backpack
            end
            wait(0.01)
        end
        wait(0.01)
        end

These are just the rough steps, so implant the changes in your code the way you want them to be.