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
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
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?
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
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)
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)
The round system works great now but this happened
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
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
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)
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)
Oh wait it works, sorry about all that confusion
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
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)