What do you want to achieve?
I want to fix my datastore so a save doesn’t wipe if I rejoin too quickly. I want to keep it simple without getting into profileservice or datastore2.
What is the issue?
The title says it all. If any player leaves and rejoins too quickly, their data gets wiped.
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local Saver = DataStoreService:GetDataStore("TEST0.20")
Players.PlayerAdded:Connect(function(player)
local Data = nil
local success, errormessage = pcall(function()
Data = Saver:GetAsync(tostring(player.UserId))
end)
if success then
if Data then
for i, v in pairs(Data) do
if not player:FindFirstChild(i) then
player:WaitForChild("leaderstats"):WaitForChild(i).Value = v
else
player:FindFirstChild(i).Value = v
end
end
end
else
player:Kick("Your data didn't save, rejoin after a few moments.")
error(errormessage)
end
end)
local function Save(player)
local SavedData = {}
for _, v in pairs(player.leaderstats:GetChildren()) do
SavedData[v.Name] = v.Value
end
for _, v in pairs(player:GetChildren()) do
if v:IsA("NumberValue") or v:IsA("StringValue") then
SavedData[v.Name] = v.Value
end
end
local success, errormessage = pcall(function()
Saver:SetAsync(tostring(player.UserId), SavedData)
end)
if not success then
error(errormessage)
end
end
Players.PlayerRemoving:Connect(Save)
game:BindToClose(function()
for _, v in pairs(Players:GetPlayers()) do
Save(v)
end
end)
At the top of the loading script, you need a BoolValue (parented to the player) to signal to the saving function that the data has loaded. Set the value to true at the very end of your loading function.
Then, in the saving function, right at the top, check the value of the BoolValue. If it is true (to signal data loading failed or didn’t finish), don’t continue with the save.
local Players = game:GetService("Players")
local DataStore2 = require('path to datastore 2')
Players.PlayerAdded:Connect(function(Player)
local success, Data = pcall(function()
local DataStore = DataStore2('Data', Player)
local ResultData = DataStore:Get()
if ResultData ~= nil then
for i, v in pairs(ResultData) do
if not Player:FindFirstChild(i) then
Player:WaitForChild("leaderstats"):WaitForChild(i).Value = v
else
Player:FindFirstChild(i).Value = v
end
end
end
end)
if success then
print('Successfully Got Data For ' ..Player.Name.."!")
else
Player:Kick("Your data didn't save, rejoin after a few moments.")
error(Player)
end
end)
local function Save(player)
local SavedData = {}
for _, v in pairs(player.leaderstats:GetChildren()) do
SavedData[v.Name] = v.Value
end
for _, v in pairs(player:GetChildren()) do
if v:IsA("NumberValue") or v:IsA("StringValue") then
SavedData[v.Name] = v.Value
end
end
local success, errormessage = pcall(function()
local DataStore = DataStore2('Data', player)
DataStore:Set(SavedData)
end)
if not success then
error(errormessage)
end
end
Players.PlayerRemoving:Connect(Save)
game:BindToClose(function()
for _, v in pairs(Players:GetPlayers()) do
Save(v)
end
end)
do this. Its because the player has no data inside that datastore.
What do you mean by this?
for the kicking out this should fix it:
Players.PlayerAdded:Connect(function(Player)
local success, Data = pcall(function()
local DataStore = DataStore2('Data', Player)
local ResultData = DataStore:Get()
if ResultData ~= nil then
for i, v in pairs(ResultData) do
if not Player:FindFirstChild(i) then
Player:WaitForChild("leaderstats"):WaitForChild(i).Value = v
else
Player:FindFirstChild(i).Value = v
end
end
end
end)
if success then
print(Data)
else
Player:Kick("Your data didn't save, rejoin after a few moments.")
error(Player)
end
end)
Like, say for example, something terrible happens in one datastore, so I want to change it to another version, resetting data or changing it to the data that was saved in that version, how would I do that?
I’ve learned to not call up the data store the moment they start a game. Give that a few moments and make sure you have a drop out of the game way to handle a data save …