Datastore doesnt work

My Datastore doesnt save, no errors or warnings

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)

api is on btw
i have no idea why

1 Like

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.

2 Likes

alright i will try that, i will reply to you if it works

1 Like

in the script, what part of the saving part of the script do i replace in the bind to close? the whole part of the playerremoving or setasync?

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)

The entire player removing function

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

Are you testing that in studio or in the client version of Roblox? Studio should print out the actual table in the output.

Im testing it in the client version

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

image

wait, my time is 50, but it was 123 in the table. do you think that could be a problem?

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)

i update the values in the datastore script

and i think the problem is getting the data because
i left the studio and my time was 132 and when i tested again it printed 132

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.

i did that and it didnt fix

i might be gone for an hour or two btw

1 Like

I will look at this script again when I wake up. I would just check the CharacterAdded block for now and see if that is why the script isn’t working.

i looked at it, and the problem i believe is loading the data, the data saves and all but it doesnt load

Try This!

Fixed Code

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"]