How to make a SAVING leaderstats in Roblox Studio!

In this post, I will show you how to make a SAVING leaderstats!

Step 1: Add a script in ServerScriptService and name it “leaderstats”.
You should have an empty script except a line that has “print("Hello World!")”. Delete it.

Step 2: Make a function when a player joins the game.

game.Players.PlayerAdded:Connect(function(player)

end)

Step 3: Add a “leaderstats” folder inside the player
Type the following code to make an in-game leaderboard(called leaderstats). You have to name it leaderstats or else it won’t work! To put the folder inside the player, you need to set its Parent to the player.

local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

Step 4: Add currencies

You need to add a currency to the leaderboard! Most people use “Coins”, so we’ll use it. You can rename it as something else if you don’t want your currency to be Coins.

local coins = Instance.new("IntValue")
coins.Name = "Coins" -- name
coins.Parent = leaderstats -- put it in the leaderstats folder so it shows up

Step 5: You’ve created a leaderboard! Test it out. But we didn’t save the Cash yet! That’s what we’ll do now.
Add a script in the leaderstats script. You don’t have to name it but it might be better if you do. If you want to name it, name it SaveScript, and once again, delete the “print("Hello World!")

Step 6: Enable API Services
Go to Game Settings in the Home tab, click security and turn on the API Services if you haven’t. If you don’t, it won’t save data AND it will result in an error!

Step 7: Get Services
In order to save things, you need to use the services. Type the following code to get them first.

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local Saver = DataStoreService:GetDataStore("SaveLeaderstats")

Step 8: Saving and Loading

You made it to the last step! You need the following code to make it save and load.

Players.PlayerAdded:Connect(function(player)
	local Data = nil
	local success, errormessage = pcall(function()
		Data = Saver:GetAsync(tostring(player.UserId)) -- sets data from DataStore
		print("Successfully loaded "..tostring(player.Name)..tostring("'s data.")) -- print that it loaded the data
	end)

	if success then
		if Data then
			for i, v in pairs(Data) do
				player:WaitForChild("leaderstats"):WaitForChild(i).Value = v
			end
		end
	else
		error(errormessage)
	end
end)

local function Save(player)
	local SavedData = {}
	for _, v in pairs(player.leaderstats:GetChildren()) do -- gets every value in the leaderstats folder
		SavedData[v.Name] = v.Value
	end

	local success, errormessage = pcall(function()
		Saver:SetAsync(tostring(player.UserId), SavedData) -- sets data when a player leaves
		print("Successfully got "..tostring(player.Name)..tostring("'s data.")) -- prints that the data has been saved
	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) -- calls the Save function to save data
	end
end)

You finished! Try it out! You’ll need to follow another tutorial to get coins, such as touching something to earn them.

If you created values in a different folder and want to save them, move the code that has the other folders created and the values in it to another script in the ServerScriptService and add the SaveScript in it. Instead of player:WaitForChild("leaderstats"):WaitForChild(i).Value = v, put player:WaitForChild("YourFolderName"):WaitForChild(i).Value = v -- replace YourFolderName with your other folder name, not leaderstats and instead of player.leaderstats:GetChildren(), put player.YourFolderName:GetChildren() -- replace YourFolderName with your Other Folder name.

And that’s basically it! I hope you enjoyed it.

FINISHED PRODUCT:

leaderstats

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

SaveScript

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local Saver = DataStoreService:GetDataStore("SaveLeaderstats")

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
				player:WaitForChild("leaderstats"):WaitForChild(i).Value = v
			end
		end
	else
		error(errormessage)
	end
end)

local function Save(player)
	local SavedData = {}
	for _, v in pairs(player.leaderstats:GetChildren()) do
		SavedData[v.Name] = v.Value
	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)
2 Likes

Some adjustments:

You can just keep this as player.UserId since it’s implictly converted to a string already

The tostrings here aren’t needed because the values in question are already strings

-- you can also write it like this:
print(`Successfully loaded {player.Name}'s data.`)

(The forum doesn’t have property syntax highlighting for it)

Same thing as above

I recommend writing it like this:

for _, v in Players:GetPlayers() do
	task.spawn(Save, v) -- calls the Save function to save data
end

This is so everyone’s data call be saved without needed to wait for the previous person’s save to finish

7 Likes