How to add a datastore to this?

I’m trying to add a datastore to my kill leaderboard. I’ve tried many different methods, but none of them seemed to work.

The script:

game.Players.PlayerAdded:Connect(function(player)
	local folder = Instance.new("Folder",player)
	folder.Name = "leaderstats"
	local currency1 = Instance.new("IntValue",folder)
	currency1.Name = "Kills"

	player.CharacterAdded:Connect(function(character)
		character:WaitForChild("Humanoid").Died:Connect(function()
			local tag = character.Humanoid:FindFirstChild("creator")
			if tag ~= nil then
				if tag.Value ~= nil then
					currency1.Value = currency1.Value + 1
				end
			end 
		end)
	end)
end)

Thanks! :smiley:

You’d need to call the Datastore service, create the datastore, and then I presume save to it in this case. See Dev Manual for more details.

Here’s what I wrote:

local myDataStore = game:GetService("DataStoreService"):GetDataStore("myDataStore")


game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local level = Instance.new("IntValue")
	level.Name = "Level"
	level.Parent = leaderstats

	local data = nil

	local success, errormessage = pcall(function()
		data = myDataStore:GetAsync(player.UserId.."-level")
	end)

	if success then
		level.Value = (data or 0)
	else
		warn("There was an error when attempting to load your data.\n"..errormessage)
	end

	while wait(180) do
		level.Value += 1
	end
end)


game.Players.PlayerRemoving:Connect(function(player)
	local success, errormessage = pcall(function()
		myDataStore:SetAsync(player.UserId.."-level", player.leaderstats.Level.Value)
	end)


	if success then
		print("Player Data has been saved!")
	else
		warn("There was an error while trying to save data.\n"..errormessage)
	end
end)

However, this breaks the other code, and gives me this warning:
Nothing comes up in the output either… Any ideas?

1 Like

If you want to store 2 values (e.g Kills and Level) you will need to use an array which will be automatically encoded by the datastore. I do also recommend using :BindToClose() to secure a better save.

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")

local StatsData = DataStoreService:GetDataStore("StatsData")

Players.PlayerAdded:Connect(function(client)
	local Leaderstats = Instance.new("Folder")
	Leaderstats.Name = "leaderstats"
	Leaderstats.Parent = client
	
	local Level = Instance.new("IntValue")
	Level.Name = "Level"
	Level.Parent = Leaderstats
	
	local Kills = Instance.new("IntValue")
	Kills.Name = "Kills"
	Kills.Parent = Leaderstats
	
	local Data
	
	local Success, Error = pcall(function()
		Data = StatsData:GetAsync(client.UserId)
	end)
	
	if Success then
		Level.Value = Data[1] or 0
		Kills.Value = Data[2] or 0
	end
end)

Players.PlayerRemoving:Connect(function(client)
	local Values = {
		client.leaderstats.Level.Value;
		client.leaderstats.Kills.Value
	}
	
	pcall(function()
		StatsData:SetAsync(client.UserId, Values)
	end)
end)

game:BindToClose(function()
	for _, client in ipairs(Players:GetPlayers()) do
		local Values = {
			client.leaderstats.Level.Value;
			client.leaderstats.Kills.Value
		}

		pcall(function()
			StatsData:SetAsync(client.UserId, Values)
		end)
	end
end)

I get this error:
ServerScriptService.DataStore:26: attempt to index nil with number - Server - DataStore:26

You can try putting it in 3 scripts: 1 for the Datastore, 1 for the levels, and 1 for the kills.

Don’t worry about that error it will only appear the first time, if you want to still get rid of it just add a pcall.

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")

local StatsData = DataStoreService:GetDataStore("StatsData")

Players.PlayerAdded:Connect(function(client)
	local Leaderstats = Instance.new("Folder")
	Leaderstats.Name = "leaderstats"
	Leaderstats.Parent = client

	local Level = Instance.new("IntValue")
	Level.Name = "Level"
	Level.Parent = Leaderstats

	local Kills = Instance.new("IntValue")
	Kills.Name = "Kills"
	Kills.Parent = Leaderstats

	local Data

	local Success, Error = pcall(function()
		Data = StatsData:GetAsync(client.UserId)
	end)

	if Success then
		pcall(function()
			Level.Value = Data[1] or 0
			Kills.Value = Data[2] or 0
		end)
	end
end)

Players.PlayerRemoving:Connect(function(client)
	local Values = {
		client.leaderstats.Level.Value;
		client.leaderstats.Kills.Value
	}

	pcall(function()
		StatsData:SetAsync(client.UserId, Values)
	end)
end)

game:BindToClose(function()
	for _, client in ipairs(Players:GetPlayers()) do
		local Values = {
			client.leaderstats.Level.Value;
			client.leaderstats.Kills.Value
		}

		pcall(function()
			StatsData:SetAsync(client.UserId, Values)
		end)
	end
end)

Where do I add my script?
This:

game.Players.PlayerAdded:Connect(function(player)
	local folder = Instance.new("Folder",player)
	folder.Name = "leaderstats"
	local currency1 = Instance.new("IntValue",folder)
	currency1.Name = "Kills"

	player.CharacterAdded:Connect(function(character)
		character:WaitForChild("Humanoid").Died:Connect(function()
			local tag = character.Humanoid:FindFirstChild("creator")
			if tag ~= nil then
				if tag.Value ~= nil then
					currency1.Value = currency1.Value + 1
				end
			end 
		end)
	end)
end)

you got some repeated code here
why not make a function that takes in the player as the argument and save the data in that function