local dataStoreService = game:GetService("DataStoreService")
local dataStore = dataStoreService:GetDataStore("PlayerData")
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Time = Instance.new("IntValue")
Time.Name = "Time"
Time.Parent = leaderstats
local Kills = Instance.new("IntValue")
Kills.Name = "Kills"
Kills.Parent = leaderstats
local playerUserId = player.UserId
local data = nil
local success, errormessage = pcall(function()
data = dataStore:GetAsync(playerUserId)
end)
if success then
print("Got player data")
else
print("fail")
warn(errormessage)
end
player.CharacterAdded:connect(function(Character)
local Humanoid = Character:FindFirstChild("Humanoid")
if Humanoid then
Humanoid.Died:connect(function()
for i, Child in pairs(Humanoid:GetChildren()) do
if Child:IsA('ObjectValue') and Child.Value and Child.Value:IsA('Player') then
local Killer = Child.Value
if Killer:FindFirstChild 'leaderstats' and Killer.leaderstats:FindFirstChild "Kills" then
local Kills = Killer.leaderstats.Kills
Kills.Value = Kills.Value + 1
end
return
end
end
end)
end
end)
if success then
if data then
Time.Value = data[1]
Kills.Value = data[2]
end
else
warn(errormessage)
end
task.spawn(function()
while task.wait(1) do
Time.Value += 1
end
end)
end)
Players.PlayerRemoving:Connect(function(player)
local leaderstats = player.leaderstats
local playerUserId = player.UserId
local data = {
Kills = leaderstats.Kills.Value;
}
local success, errormessage = pcall(function()
dataStore:SetAsync(playerUserId, data)
end)
if success then
print("Player data saved successfully.")
else
print("Player data did not save.")
warn(errormessage)
end
end)
I pretty much say this on every datastore post but do one of these two things at the end of the script:
game:BindToClose(function()
task.wait(3)
end)
The one that most people use is this:
game:BindToClose(function()
for _, player in pairs(game.Players:GetPlayers()) do
SaveData(player) --Replace the existing saving part of your script with a function
end
end)
The issue is that the server closes before it can save your data, which is why it doesn’t print anything.
local function SaveData(player)
local leaderstats = player.leaderstats
local playerUserId = player.UserId
local data = {
Kills = leaderstats.Kills.Value;
}
local success, errormessage = pcall(function()
dataStore:SetAsync(playerUserId, data)
end)
if success then
print("Player data saved successfully.")
else
print("Player data did not save.")
warn(errormessage)
end
end
Players.PlayerRemoving:Connect(SaveData)
game:BindToClose(function()
for _, player in pairs(game.Players:GetPlayers()) do
SaveData(player)
end
end)
I’ve replaced the playerremoving function but added one tweak to save the time
ive joined and rejoined the game, but my time and kills start at 0 and dont save
the difference is i added Time = leaderstats.Time.Value; 7 lines below the function to save
here sthe script
local dataStore = dataStoreService:GetDataStore("PlayerData")
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
print("testing updat2e")
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Time = Instance.new("IntValue")
Time.Name = "Time"
Time.Parent = leaderstats
local Kills = Instance.new("IntValue")
Kills.Name = "Kills"
Kills.Parent = leaderstats
local playerUserId = player.UserId
local data = nil
local success, errormessage = pcall(function()
data = dataStore:GetAsync(playerUserId)
end)
if success then
print("Got player data")
else
print("fail")
warn(errormessage)
end
player.CharacterAdded:connect(function(Character)
local Humanoid = Character:FindFirstChild("Humanoid")
if Humanoid then
Humanoid.Died:connect(function()
for i, Child in pairs(Humanoid:GetChildren()) do
if Child:IsA('ObjectValue') and Child.Value and Child.Value:IsA('Player') then
local Killer = Child.Value
if Killer:FindFirstChild 'leaderstats' and Killer.leaderstats:FindFirstChild "Kills" then
local Kills = Killer.leaderstats.Kills
Kills.Value = Kills.Value + 1
end
return
end
end
end)
end
end)
if success then
if data then
Time.Value = data[1]
Kills.Value = data[2]
end
else
warn(errormessage)
end
task.spawn(function()
while task.wait(1) do
Time.Value += 1
end
end)
end)
local function SaveData(player)
local leaderstats = player.leaderstats
local playerUserId = player.UserId
local data = {
Kills = leaderstats.Kills.Value;
Time = leaderstats.Time.Value;
}
local success, errormessage = pcall(function()
dataStore:SetAsync(playerUserId, data)
end)
if success then
print("Player data saved successfully.")
else
print("Player data did not save.")
warn(errormessage)
end
end
Players.PlayerRemoving:Connect(SaveData)
game:BindToClose(function()
for _, player in pairs(game.Players:GetPlayers()) do
SaveData(player)
end
end)
Is it printing anything after your saved pcall? Also, I don’t think that this has anything to do with it but change local data = nil to local data in the loading part of your script.
load data pcall thing
local data --remove '= nil' from the variable
local success, errormessage = pcall(function()
data = dataStore:GetAsync(playerUserId)
end)
if success then
print(data)
end
By the way, print out the data after it is loaded to see if it is an issue with the saving part of your script or the loading part of your script.
this is what printing data comes out with
and making local data = nil into local data didnt fix it
the error is not about the datastore, its about a global leaderboard
Test it in studio. Also, I just noticed that you aren’t actually applying the data to your variables.
if success then
print("Got player data")
Kills.Value = data.Kills --i might be writing this incorrectly
Time.Value = data.Time --Make sure you are saving this to the table
else
print("fail")
warn(errormessage)
end
Maybe. Do you update your time/kill values in a separate script? Like I said in my previous reply, it doesn’t look like you are loading the values anywhere.
Updated Script
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Time = Instance.new("IntValue")
Time.Name = "Time"
Time.Parent = leaderstats
local Kills = Instance.new("IntValue")
Kills.Name = "Kills"
Kills.Parent = leaderstats
local playerUserId = player.UserId
local data
local success, errormessage = pcall(function()
data = dataStore:GetAsync(playerUserId)
end)
if success then
print("Got player data")
Kills.Value = data.Kills
Time.Value = data.Time
else
print("fail")
warn(errormessage)
end
player.CharacterAdded:connect(function(Character)
local Humanoid = Character:FindFirstChild("Humanoid")
if Humanoid then
Humanoid.Died:connect(function()
for i, Child in pairs(Humanoid:GetChildren()) do
if Child:IsA('ObjectValue') and Child.Value and Child.Value:IsA('Player') then
local Killer = Child.Value
if Killer:FindFirstChild 'leaderstats' and Killer.leaderstats:FindFirstChild "Kills" then
local Kills = Killer.leaderstats.Kills
Kills.Value = Kills.Value + 1
end
return
end
end
end)
end
end)
if success then
if data then
Time.Value = data[1]
Kills.Value = data[2]
end
else
warn(errormessage)
end
task.spawn(function()
while task.wait(1) do
Time.Value += 1
end
end)
end)
Wait i’m dumb, you update the values at the bottom. Maybe try updating the values before the CharacterAdded part of your script.
another updated script
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Time = Instance.new("IntValue")
Time.Name = "Time"
Time.Parent = leaderstats
local Kills = Instance.new("IntValue")
Kills.Name = "Kills"
Kills.Parent = leaderstats
local playerUserId = player.UserId
local data
local success, errormessage = pcall(function()
data = dataStore:GetAsync(playerUserId)
end)
if success then
print("Got player data")
Kills.Value = data[1]
Time.Value = data[2]
else
print("fail")
warn(errormessage)
end
player.CharacterAdded:connect(function(Character)
local Humanoid = Character:FindFirstChild("Humanoid")
if Humanoid then
Humanoid.Died:connect(function()
for i, Child in pairs(Humanoid:GetChildren()) do
if Child:IsA('ObjectValue') and Child.Value and Child.Value:IsA('Player') then
local Killer = Child.Value
if Killer:FindFirstChild 'leaderstats' and Killer.leaderstats:FindFirstChild "Kills" then
local Kills = Killer.leaderstats.Kills
Kills.Value = Kills.Value + 1
end
return
end
end
end)
end
end)
task.spawn(function()
while task.wait(1) do
Time.Value += 1
end
end)
end)
I’m guessing that your characteradded block is somehow preventing the script from updating the values.
local Players = game:GetService('Players')
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("PlayerData")
local function OnPlayerAdded(player)
local leaderstats = Instance.new("Folder", player)
leaderstats.Name = "leaderstats"
local Kills = Instance.new("IntValue", leaderstats)
Kills.Name = "Kills "
local Time = Instance.new("IntValue", leaderstats)
Time.Name = "Time "
local data = nil
local success, errormessage = pcall(function()
data = dataStore:GetAsync("Player_"..player.UserId)
end)
if success and data ~= nil then
print("Player data loaded successfully!")
Kills.Value = data['Kills']
Time.Value = data['Time']
elseif not success then
print("Error getting player data!")
warn(errormessage)
else
print(player.Name..' is a new player.')
end
end
local function CreateTable(player)
local PlayerData = {}
for _, Value in pairs(player.leaderstats:GetChildren()) do
PlayerData[Value.Name] = Value.Value
end
return PlayerData
end
local function OnPlayerRemoving(player)
local PlayerData = CreateTable(player)
local success, errormessage = pcall(function()
dataStore:SetAsync("Player_"..player.UserId, PlayerData)
end)
if success then
print("Player data was successfuly saved!")
else
print("Error saving data!")
warn(errormessage)
end
end
Players.PlayerAdded:Connect(OnPlayerAdded)
Players.PlayerRemoving:Connect(OnPlayerRemoving)
game:BindToClose(function()
for i, player in pairs(Players:GetChildren()) do
OnPlayerRemoving(player)
end
end)
How does it work?
This is basically compacting the code into a table.
It gets the data and unpacks it and loads it, when the player leaves it compacts all the current information into table and saves it.
eg,
Last saved data
--Player leaves the game with 5 kills and 300 time.
data = {
["Kills"] = 5;
["Time"] = 300;
}
Loading last saved data
--Player joins the game again. It gets the data then unpacks it.
--Saved Data
data = {
["Kills"] = 5;
["Time"] = 300;
}
--Loading Data.
Kills.Value = data["Kills"]
Time.Value = data["Time"]