How do I give the remaining survivors Points and Survivals for surviving

Currently I am working on finishing up the round system of my game so it can give players Points and Survivals for surviving the round. And if it’s possible, Different amounts of points for surviving a specific tornado. I have looked into this kind of stuff but it didn’t help out much and I am confused. If someone could help that would be great!

The current script I have is here below

local Status = game.ReplicatedStorage.Status
local PlayerTP = game.Players.LocalPlayer
local player = game.Players.LocalPlayer
local Cloud = game.ServerStorage.Cloud

--Maps Variables
local MapsFolder = game.Lighting.Maps
local Maps = MapsFolder:GetChildren()
--

--Tornado List
local Tornadoes = {
	"EF1",
	"EF2","EF2",
	"EF3","EF3","EF3","EF3",
	"EF4","EF4","EF4","EF4","EF4",
	"EF5", "EF5", "EF5","EF5",
	"Sharknado","Sharknado","Sharknado",
}
--

--Tornadoes
local EF5 = game.ServerStorage.Objects.EF5
local EF4 = game.ServerStorage.Objects.EF4
local EF3 = game.ServerStorage.Objects.EF3
local EF2 = game.ServerStorage.Objects.EF2
local EF1 = game.ServerStorage.Objects.EF1
local Sharknado = game.ServerStorage.Objects.Sharknado
--


local TeleportGUI = workspace.Teleport


--Timer
local timeForGameToStart = 5
local timeToEndGame = 80
--

--Loop
while true do

	local ChosenMap = Maps[math.random(1, #Maps)]
	local MapClone = ChosenMap:Clone()

	wait(1)

	Status.Value = "Game starting soon"

	wait(timeForGameToStart)

	Status.Value = "Selecting Map..."

	wait(3)

	Status.Value = ChosenMap.Name.. " has been chosen"

	MapClone.Parent = game.Workspace

	wait(3)

	Status.Value = "Teleporting Players..."

	for i,player in pairs(game.Players:GetChildren()) do
		local char = player.Character
		char.HumanoidRootPart.CFrame = CFrame.new(-163, 14, 10)
	end
	
	wait(3)

	Status.Value = "A Tornado has been sighted by a weather radar"

	wait(5)

	Status.Value = "There is imminent danger to life and property"

	wait(5)

	Status.Value = "Move to an interior room on the lowest floor of a sturdy building"

	wait(5)

	Status.Value = "Try to stay safe and protect loved ones"

	wait(5)

	TeleportGUI.Parent = game.StarterGui

	--Picks Random Tornado
	local Tornado = Tornadoes[math.random(1, #Tornadoes)]
	--
	
	Cloud.Parent = workspace.TornadoFolder
	
	--Selects tornado and what they do	
	if Tornado == "EF5" then

		EF5.Parent = workspace.TornadoFolder
		Status.Value = "AN EF5 HAS FORMED IN THE AREA, SEEK SHELTER AS DAMAGE IS CATASTROPHIC"

	elseif Tornado == "EF4" then
		
		EF4.Parent = workspace.TornadoFolder
		Status.Value = "AN EF4 HAS FORMED, DAMAGE CAN BE DEVASTATING"
		
	elseif Tornado == "EF3" then
		
		EF3.Parent = workspace.TornadoFolder
		Status.Value = "AN EF3 HAS FORMED IN THE AREA, SEEK SHELTER IMMEDIATELY"
		
	elseif Tornado == "EF2" then
		
		EF2.Parent = workspace.TornadoFolder
		Status.Value = "AN EF2 HAS FORMED, DAMAGE CAN BE SEVERE"
		
	elseif Tornado == "EF1" then
		
		EF1.Parent = workspace.TornadoFolder
		Status.Value = "An EF1 has formed in the area, it causes slight damage but still find shelter"
		
	elseif Tornado == "Sharknado" then
		
		Sharknado.Parent = workspace.TornadoFolder
		Status.Value = "A TORNADO THAT SHOOTS OUT SHARKS HAS FORMED, SEEK SHELTER AS DAMAGE CAN BE DEVASTATING"
		
	end
	--

	--Game End
	wait(timeToEndGame)
	TeleportGUI.Parent = game.Workspace
	--

	--Game Reset thing
	Sharknado.Parent = game.ServerStorage.Objects
	EF5.Parent = game.ServerStorage.Objects
	EF4.Parent = game.ServerStorage.Objects
	EF3.Parent = game.ServerStorage.Objects
	EF2.Parent = game.ServerStorage.Objects
	EF1.Parent = game.ServerStorage.Objects
	Cloud.Parent = game.ServerStorage
	--

	--GameEnd
	Status.Value = "It seems that the tornado is gone"

	wait(4)

	Status.Value = "It is safe to be outside now"

	wait(4)

	Status.Value = "Resetting Game..."
	--

	--Teleport
	for i,player in pairs(game.Players:GetChildren()) do
		player:LoadCharacter()
	end
	--

	--Reset Map
	MapClone:Destroy()
	wait(1)
	--
end
3 Likes

I hath returned!

Well, there are some things that I could see that could be changed here

You referenced the LocalPlayer twice in your script, also if this is server-sided you can’t define it like that anyways as the LocalPlayer only works if it’s on the local-side (Or a LocalScript)

You’re cloning this to the StarterGui, which won’t account for the current players that are in the game but rather new players that joined in after this line is ran (You could probably put this in the PlayerGui instead if that’s what you meant)

Now for the OP itself, what you could do is create a BoolValue & IntValues for every Player that’s currently in the server that’ll detect who has died or not, that would probably be the simplest way on doing it via a PlayerAdded event

--This is a Server Script, preferably located inside ServerScriptService
game.Players.PlayerAdded:Connect(function(Player)
    local leaderstats = Instance.new("Folder")
    leaderstats.Name = "leaderstats"
    leaderstats.Parent = Player

    local DeadCheck = Instance.new("BoolValue")
    DeadCheck.Name = "DeadCheck"
    DeadCheck.Parent = Player
    --No need to set its value as its by default, false

    local Points = Instance.new("IntValue")
    Points.Name = "Points"
    Points.Parent = leaderstats

    local Survivals = Instance.new("Survivals")
    Survivals.Name = "Survivals"
    Survivals.Parent = leaderstats

    Player.CharacterAdded:Connect(function(Character)
        local Humanoid = Character:WaitForChild("Humanoid")
       
        Humanoid.Died:Connect(function()
            DeadCheck.Value = true --We're setting this to true cause this player oofed up
        end)
    end)
end)

Then after the round ends in your script, you can yet again loop through every player & check if they survived the Tornado or not:

	--Teleport
	for i,player in pairs(game.Players:GetChildren()) do
        if player.DeadCheck.Value == false then
            --This is where you'd reward points depending on which tornado they survived
        end
		player:LoadCharacter()
	end
3 Likes

It seems to work pretty well but the problem is that it for some reason it still gives players who are dead points and survivals. Is there something else that I need to add or did I get something incorrect.

The leaderstats script I have right now is here below

local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("GemSaveSystem")
local ds2 = datastore:GetDataStore("CashSaveSystem")

game.Players.PlayerAdded:connect(function(plr)
	local folder = Instance.new("Folder", plr)
	folder.Name = "leaderstats"
	local Survivals = Instance.new("IntValue", folder)
	Survivals.Name = "Survivals"
	local Points = Instance.new("IntValue", folder)
	Points.Name = "Points"
	local DeadCheck = Instance.new("BoolValue")
	DeadCheck.Name = "DeadCheck"
	DeadCheck.Parent = plr

	Survivals.Value = ds1:GetAsync(plr.UserId) or 0
	ds1:SetAsync(plr.UserId, Survivals.Value)

	Points.Value = ds2:GetAsync(plr.UserId) or 0
	ds2:SetAsync(plr.UserId, Points.Value)

	Survivals.Changed:connect(function()
		ds1:SetAsync(plr.UserId, Survivals.Value)
	end)
		
	Points.Changed:connect(function()
		ds2:SetAsync(plr.UserId, Points.Value)	
	end)
			
	local DeadCheck = Instance.new("BoolValue")
	DeadCheck.Name = "DeadCheck"
	DeadCheck.Parent = plr
	--No need to set its value as its by default, false
		
	plr.CharacterAdded:Connect(function(Character)
		local Humanoid = Character:WaitForChild("Humanoid")
		
		Humanoid.Died:Connect(function()
			DeadCheck.Value = true --We're setting this to true cause this player oofed up
		end)
	end)
end)

Is there something that I need to add into the main game handler to reset the “DeadCheck” once the players start the round?

1 Like

Hm, could you try this whenever you attempt to teleport all players back into the game?

	--Teleport
	for i,player in pairs(game.Players:GetChildren()) do
        print(player.DeadCheck.Value)

        if player.DeadCheck.Value == false then
            --This is where you'd reward points depending on which tornado they survived
        end
		player:LoadCharacter()
	end

It wouldn’t hurt to debug & use print statements, try also printing what DeadCheck.Value gives you whenever a Character’s Humanoid dies

1 Like

This happened when I tested it, My friend survived the round while I died yet we both got points

    plr.CharacterAdded:Connect(function(Character)
		local Humanoid = Character:WaitForChild("Humanoid")
		
		Humanoid.Died:Connect(function()
			DeadCheck.Value = true --We're setting this to true cause this player oofed up
            print(DeadCheck.Value)
		end)
	end)

What about this?

Sorry about the late response but this also doesn’t work as I died in the round yet it still gave me points. It printed out false like it always does.

I think I may know what the issue could be

Since you’re calling a yielding function (GetAsync), it’s basically waiting until there’s some sort of valid data that could be found in the player or not which is why the CharacterAdded Event is not picking up ahead of time

Try to order your script to be like this perhaps? I’d also recommend encasing your DataStore functions inside pcalls to prevent it from erroring at all

local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("GemSaveSystem")
local ds2 = datastore:GetDataStore("CashSaveSystem")

game.Players.PlayerAdded:connect(function(plr)
	local folder = Instance.new("Folder", plr)
	folder.Name = "leaderstats"
	local Survivals = Instance.new("IntValue", folder)
	Survivals.Name = "Survivals"
	local Points = Instance.new("IntValue", folder)
	Points.Name = "Points"
	local DeadCheck = Instance.new("BoolValue")
	DeadCheck.Name = "DeadCheck"
	DeadCheck.Parent = plr

	plr.CharacterAdded:Connect(function(Character)
		local Humanoid = Character:WaitForChild("Humanoid")
		
		Humanoid.Died:Connect(function()
			DeadCheck.Value = true --We're setting this to true cause this player oofed up
		end)
	end)

    local Data
    local success, whoops = pcall(function()
	    Data = ds1:GetAsync(plr.UserId) 
    end)

    if success and Data then
        Survivals.Value = Data
        Points.Value = Data
    else
        warn(whoops)
        Survivals.Value = 0
        Points.Value = 0
    end

	Survivals.Changed:Connect(function()
		local success, whoops = pcall(function()
			ds1:SetAsync(plr.UserId, Survivals.Value)
		end)
		
		if success then
			print("Data successfully saved!")
		else
			warn(whoops)
		end
	end)

	Points.Changed:Connect(function()
		local success, whoops = pcall(function()
			ds1:SetAsync(plr.UserId, Points.Value)
		end)

		if success then
			print("Data successfully saved!")
		else
			warn(whoops)
		end
	end)
			
	local DeadCheck = Instance.new("BoolValue")
	DeadCheck.Name = "DeadCheck"
	DeadCheck.Parent = plr
	--No need to set its value as its by default, false

end)
1 Like

The round system works great now but this happened
testesttestestest
The survivals are the same amount as points in the game for some reason
Edit: Forgot to mention that it somewhat also breaks the save system as both survivals and points are set to one when I rejoin/disconnect
testiung

Oh I found it

You’re saving the same DataStore values again, so what you’d probably need to do is instead create a custom function in order to properly save both of their values altogether

It’s been a while since I’ve last figured out how DataStores work, so I apologize for the delay :sweat_smile:

local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("GemSaveSystem")
local ds2 = datastore:GetDataStore("CashSaveSystem")

game.Players.PlayerAdded:connect(function(plr)
	local folder = Instance.new("Folder", plr)
	folder.Name = "leaderstats"
	local Survivals = Instance.new("IntValue", folder)
	Survivals.Name = "Survivals"
	local Points = Instance.new("IntValue", folder)
	Points.Name = "Points"
	local DeadCheck = Instance.new("BoolValue")
	DeadCheck.Name = "DeadCheck"
	DeadCheck.Parent = plr

	plr.CharacterAdded:Connect(function(Character)
		local Humanoid = Character:WaitForChild("Humanoid")
		
		Humanoid.Died:Connect(function()
			DeadCheck.Value = true --We're setting this to true cause this player oofed up
		end)
	end)

    local Data
    local success, whoops = pcall(function()
	    Data = ds1:GetAsync(plr.UserId) 
    end)

    if success and Data then
        Survivals.Value = Data[1]
        Points.Value = Data[2]
    else
        warn(whoops)
        Survivals.Value = 0
        Points.Value = 0
    end

	local function SaveData()
        local DataToSave = {
            Survivals.Value,
            Points.Value
        }
		local success, whoops = pcall(function()
			ds1:SetAsync(plr.UserId, DataToSave)
		end)
		
		if success then
			print("Data successfully saved!")
		else
			warn(whoops)
		end
	end)
        Survivals.Changed:Connect(SaveData)
	Points.Changed:Connect(SaveData)	
	local DeadCheck = Instance.new("BoolValue")
	DeadCheck.Name = "DeadCheck"
	DeadCheck.Parent = plr
	--No need to set its value as its by default, false

end)

I think this should work

Alright I tried this and the round system and things work just fine but the DataStore doesn’t save and I get this error.
Capture

What…?

That shouldn’t happen though, as that should be a valid conditional statement

Are you using the same script I’m using to make it work?

local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("GemSaveSystem")
local ds2 = datastore:GetDataStore("CashSaveSystem")

game.Players.PlayerAdded:connect(function(plr)
	local folder = Instance.new("Folder", plr)
	folder.Name = "leaderstats"
	local Survivals = Instance.new("IntValue", folder)
	Survivals.Name = "Survivals"
	local Points = Instance.new("IntValue", folder)
	Points.Name = "Points"
	local DeadCheck = Instance.new("BoolValue")
	DeadCheck.Name = "DeadCheck"
	DeadCheck.Parent = plr

	plr.CharacterAdded:Connect(function(Character)
		local Humanoid = Character:WaitForChild("Humanoid")

		Humanoid.Died:Connect(function()
			DeadCheck.Value = true --We're setting this to true cause this player oofed up
		end)
	end)

	local Data
	local success, whoops = pcall(function()
		Data = ds1:GetAsync(plr.UserId) 
	end)

	if success and Data then
		Survivals.Value = Data[1]
		Points.Value = Data[2]
	else
		warn(whoops)
		Survivals.Value = 0
		Points.Value = 0
	end

	local function SaveData()
		local DataToSave = {
			Survivals.Value,
			Points.Value
		}
		local success, whoops = pcall(function()
			ds1:SetAsync(plr.UserId, DataToSave)
		end)

		if success then
			print("Data successfully saved!")
		else
			warn(whoops)
		end
	end

	Survivals.Changed:Connect(SaveData)
	Points.Changed:Connect(SaveData)	
	--No need to set its value as its by default, false

end)

Yes I am using the script you just sent and the problem sends me here
Capture2

Idk what you’re doing then, it’s completely working fine for me

image

Here’s the place file where I did it:

ThanksDataStores.rbxl (26.2 KB)

1 Like

Oh wait it works, sorry about all that confusion :sweat_smile:
I guess it was something wrong with playing solo or I forgot to paste something in.
But thank you so much for the help!

Hey! Sorry about replying here again, but I’ve noticed a big problem with the system. I am currently working on the sequel for this game and there seems to be a really abusive bug with the survival system that lets players rejoin to get survivals at the end of the round or just join in the middle of a game and win. If you could help me out that would be great!

Possibly make the deadcheck on default true and set it to false for every player when a new round starts, so people cant join in the middle of a round and get points or rejoin to get another chance

1 Like

I might be doing this wrong but the code I tried doing was this

	for i, plr in pairs(game.Players:GetChildren()) do

		local xOffset = math.random(-100, 100)
		local zOffset = math.random(-100, 100)
		
		plr.Character.HumanoidRootPart.CFrame = CFrame.new(-38 + xOffset, 5.5, 46 + zOffset)
		
		plr.DeadCheck.Value = false
		
	end

and for the deadcheck value is this when players join/die

	Players.PlayerAdded:Connect(function(player)
		player.leaderstats.DeadCheck.Value = true
	end)
	
	plr.CharacterAdded:Connect(function(Character)
		local Humanoid = Character:WaitForChild("Humanoid")

		Humanoid.Died:Connect(function()
			DeadCheck.Value = true --We're setting this to true cause this player oofed up
		end)
	end)