--Updated Code and Question--<<
When the player joins the game, if their data is successfully loaded, or they are a new player, the script sets a flag(setting bool value to true) to show that their data can be saved. If their data fails to load, this value is set to false.
local store = game:GetService("DataStoreService")
local getstore = store:GetDataStore("Playerstats1")
local runservice = game:GetService("RunService")
local serverstorage = game:GetService("ServerStorage")
local writedata = function(key, datatable, plrfolder)
local cansave = plrfolder:FindFirstChild("dataloaded")
if not cansave then return end
if not cansave.Value == true then return end
if cansave.Value == true then
local succeed, errored = pcall(function()
getstore:SetAsync(key, datatable)
end)
if succeed then
print("New Data saved successfully")
else
warn("Newdata has not been saved. Reason: "..errored)
end
end
end
game:GetService("Players").PlayerAdded:Connect(function(plr)
local playerfolder = serverstorage:WaitForChild("PlayerData")
local stats = Instance.new("Folder")
stats.Name = tostring(plr.UserId)
local level = Instance.new("IntValue", stats)
level.Name = "Level"
local experience = Instance.new("IntValue", stats)
experience.Name = "Experience"
local berries = Instance.new("IntValue", stats)
berries.Name = "Berries"
local power = Instance.new("IntValue", stats)
power.Name = "Power"
local melee = Instance.new("IntValue", stats)
melee.Name = "Melee"
local weapon = Instance.new("IntValue", stats)
weapon.Name = "Weapon"
local fruit = Instance.new("IntValue", stats)
fruit.Name = "Fruit"
local dataloaded = Instance.new("BoolValue", stats)
dataloaded.Name = "dataloaded"
local key = plr.UserId
local savedvalues
local success, errormessage = pcall(function()
savedvalues = getstore:GetAsync(key)
end)
if success then
if savedvalues ~= nil then
level.Value = savedvalues[1]
experience.Value = savedvalues[2]
berries.Value = savedvalues[3]
power.Value = savedvalues[4]
melee.Value = savedvalues[5]
weapon.Value = savedvalues[6]
fruit.Value = savedvalues[7]
dataloaded.Value = true
else
--new player
level.Value = 1
experience.Value = 0
berries.Value = 0
power.Value = 1
melee.Value = 1
weapon.Value = 1
fruit.Value = 0
dataloaded.Value = true
local valuestosave = {level.Value, experience.Value, berries.Value, power.Value, melee.Value,
weapon.Value, fruit.Value}
writedata(key, valuestosave)
end
else
--failed to load data
dataloaded.Value = false
wait()
plr:Kick("Failed to load data. Rejoin to try again.")
end
stats.Parent = playerfolder
end)
local updatedata = function(plr)
local key = plr.UserId
local playerfolder = serverstorage:WaitForChild("PlayerData")
local mydata = playerfolder:FindFirstChild(tostring(plr.UserId))
if not mydata then return end
local dataloaded = mydata:FindFirstChild("dataloaded")
local level = mydata:FindFirstChild("Level")
local experience = mydata:FindFirstChild("Experience")
local berries = mydata:FindFirstChild("Berries")
local power = mydata:FindFirstChild("Power")
local melee = mydata:FindFirstChild("Melee")
local weapon = mydata:FindFirstChild("Weapon")
local fruit = mydata:FindFirstChild("Fruit")
-----------------------------------------------------------
if dataloaded == nil then
plr:Kick()
else
if dataloaded.Value == false then
plr:Kick()
end
end
-----------------------------------------------------------
local valuestosave = {level.Value, experience.Value, berries.Value, power.Value,
melee.Value, weapon.Value, fruit.Value}
local successfully, warningmessage = pcall(function()
getstore:SetAsync(key, valuestosave)
end)
if successfully then
--data successfully saved
else
warn("warning, data could not be saved! Retrying!")
local retry_count = 0
while retry_count <6 do
wait(60)
local success, errormessage = pcall(function()
getstore:SetAsync(key, valuestosave)
end)
if success then
break
else
retry_count = retry_count + 1
end
end
end
end
game:GetService("Players").PlayerRemoving:Connect(updatedata)
game:BindToClose(function()
if runservice:IsStudio() then
print("is studio")
return
else
if not runservice:IsStudio() then
print("not in studio")
for i, v in pairs(game:GetService("Players"):GetPlayers()) do
updatedata(v)
end
end
end
end)
Is it a good idea to rely on a bool value to decide whether or not the data should be saved? Wouldn't an exploiter be able to change this value?

5 comments
Saving a lot of things at once could make it so that the game doesnt save if a lot of people leave. Also this code could cause a lot of data loss maybe
any recommendations?
Yeah don't use 4 compartments to save data within.
I've just updated my code. Thanks for the Input
In general, value objects should not be used to store data like this. This is a bad practice that has carried over from the pre-FilteringEnabled days when it was an easy way to pass values between client and server. Nowadays, this doesn't work, and you should just store player data in a table.