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

Making a round script, what is the best way to get the remaining players alive and ending the game?

Asked by 6 years ago

I'm wondering the best way to check the amount of players remaining in a round. If I do:

hum.Died:connect(function()
    alive[player][1] = false
    checkAlive()
end)

then I'm scared the two players will tie and the game will end twice.. or is the best option to add a game ending debounce?? Here's my script so far:

--// Services
local ws = game:GetService("Workspace");
local pls = game:GetService("Players");
local repstr = game:GetService("ReplicatedStorage");
local ss = game:GetService("ServerStorage");

--// References
local gameFolder = Instance.new("Folder", ws)
gameFolder.Name = ".GameSettings" -- Has . in the beginning because hopefully the player GameSettings doesn't join lol

local alive = {} -- alive[player] = {PLAYING(TRUE/FALSE, KILLS/POINTS}
local playing = {} -- playing[player] = true/false

--// Variables
local vars = {"GameState", "Intermission"}
local varInfo = { -- Value type, default value
    ["GameState"] = {"StringValue", ""};
    ["Intermission"] = {"IntValue", 0}
};

for i = 1,#vars do
    local newValue = Instance.new(varInfo[vars[i]][1], gameFolder)
    newValue.Value = varInfo[vars[i]][2]
end

--// Game functions (intermission, begin, end, etc)

function checkAlive()
    a = 0
    for _,player in pairs(pls:GetPlayers()) do
        pcall(function() -- just incase the player isnt even in the dictionary
            if alive[player][1] == true then
            a = a+1
        end)
    end
    return a
end

function intermission(startTime, gameMode) -- ignore this im finishing this later on cuz ez
    local timerValue = gameFolder:WaitForChild("Intermission")
end

function beginGame(gameMode)
    for _,player in pairs(pls:GetPlayers()) do
        if playing[player] == true then -- if player is marked as playing, then let him join!!
            alive[player] = {true, 0}

            player:LoadCharacter()
            repeat wait() until player.Character
            local hum = player.Character:WaitForChild("Humanoid")
            hum.Died:connect(function()
                alive[player][1] = false 
                checkAlive() -- can do the ending after this blablabla
            end)
        end
    end
end

1 answer

Log in to vote
0
Answered by 6 years ago
Edited 6 years ago

Events will not run at the same time so the game will never end twice. But you need to consider that a player may leave the game resulting in the function checkAlive not running at all.

Using a table is a good way to keep track of who is ingame or not but I would remove the players when they die instead.

You also do not need to add a pcall into the checkAlive function as you should be checking if the player is not nil.

Example:-

-- services
local plrServ = game:GetService("Players");

-- vars
local alivePlayers = {}
local playingList = {}

local function checkAlive()
    local i = 0
    for _, _ in pairs(alivePlayers) do
        i = i + 1 -- inc player count
    end
    print('Players alive', i)
    return i
end

local function beginGame()

    alivePlayers = {} -- reset data each round to make surre it has no errors

     for _,plr in pairs(plrServ:GetPlayers()) do
        if playingList[plr] then -- if plr is in the list ie not nil

            alivePlayers[plr] = {true, 0} -- not sure about the data
            plr:LoadCharacter() -- will cause the script to wait (yield)

            -- warning player could leave the game or reset befor the script connects
            -- the died event.
            if plr.Character then

                -- wait for 10 seconds player could also leave the game
                local hum = plr.Character:WaitForChild('Humanoid', 10) 
                if hum then
                    hum.Died:connect(function()
                        alivePlayers[plr] = nil -- clear plr from list
                        checkAlive()
                    end)
                else
                    -- needs more checks
                end
            else
                -- no character needs more checks
            end

        end
    end
end

plrServ.PlayerRemoving:Connect(function(plr)
    alivePlayers[plr] = nil -- clear the player from the list even if they are not in the list
    playingList[plr] = nil
end)

The main issue is when the script pauses (yeilds, calls a wait function) as players could leave the game reset their character causing your game to go out of sync. I think it would be best to just move the players torso as this will not yield in any way. This means the player setup can be done without being interupted.

I hope this helps please comment if you have any more questions.

Ad

Answer this question