Help with saving leaderstats!

Need help saving these folders and values as I have watched numerous tutorials and still don’t know how to save them,
the reason I have a folder inside of the leaderstats is because I want that value in that folder to not be visible.
(There is not much to this script because I just wanted to show you guys the parts that I want to be saved)

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

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

	local Multiplier = Instance.new("IntValue")
	Multiplier.Name = "Multiplier"
	Multiplier.Parent = stat

Any help appreciated!

2 Likes

I’d recommend you checking the Dev Wiki, you could see there a full guide on DataStore.
In addition to that, you could watch some tutorials on youtube, there are so many.
If that’s not enough, you could watch these posts that’ve been asked before

Best of luck!

There are various ways you could save your data, as well as various tutorials on YouTube and Posts on the forum,

Hope you find a satisfiying solution!

local Players = game:GetService("Players")
local TestService = game:GetService("TestService")
local RunService = game:GetService("RunService")
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("DataStoreValues") --Name the DataStore whatever you want

Players.PlayerAdded:Connect(function(player)

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


	local stat = Instance.new('Folder')
	stat.Name = 'stat'
    stat.Parent = leaderstats

    local Clicks = Instance.new('IntValue')
    Clicks.Name = 'Clicks'
    Clicks.Parent = leaderstats
    Clicks.Value = 0
   
    local Multiplier = Instance.new("IntValue")
    Multiplier.Name = 'Multiplier'
    Multiplier.Parent = stat

	local value1Data = Clicks
    local value2Data = Multiplier

	local s, e = pcall(function()
		value1Data = DataStore:GetAsync(player.UserId..'-Value1') or 0 --check if they have data, if not it'll be "0"
        value2Data = DataStore:GetAsync(player.UserId..'-Value2') or 0
	end)

	if s then
		Clicks.Value = value1Data --setting data if its success
        Multiplier.Value = value2Data
	else
		TestService:Error(e)  --if not success then we error it to the console
	end
end)

Players.PlayerRemoving:Connect(function(player)
local s, e = pcall(function()
	DataStore:SetAsync(player.UserId..'-Value1', player.leaderstats.Clicks.Value) --setting data
    DataStore:SetAsync(player.UserId..'-Value2', player.stat.Multiplier.Value)
	end)
	if not s then TestService:Error(e) 
	end
end)

game:BindToClose(function(player)
      if not RunService:IsStudio() then
          local s, e = pcall(function()
	      DataStore:SetAsync(player.UserId..'-Value1', player.leaderstats.Clicks.Value) --setting data
          DataStore:SetAsync(player.UserId..'-Value2', player.stat.Multiplier.Value)
	end)
	if not s then TestService:Error(e) 
	end

       end)
end)
2 Likes

You could shorten this and use tables to store your data in ( each one will have a unique key)

4 Likes
--/ Services
local Players = game:GetService('Players')
local DataStoreService = game:GetService('DataStoreService')

--/ Variables
local DataStore = DataStoreService:GetDataStore('CurrencySave')

--/ Code
Players.PlayerAdded:Connect(function(Player)
	local leaderstats = Instance.new('Folder')
	leaderstats.Name = 'leaderstats'
	leaderstats.Parent = Player
	
	local stat = Instance.new('Folder')
	stat.Name = 'stat'
	stat.Parent = leaderstats
	
	local Clicks = Instance.new('IntValue')
	Clicks.Name = 'Clicks'
	Clicks.Parent = leaderstats
	
	local Multiplier = Instance.new('IntValue')
	Multiplier.Name = 'Multiplier'
	Multiplier.Parent = stat
	
	local success, oops = pcall(function()
		Clicks.Value = DataStore:GetAsync(Player.UserId..'_Clicks') or 0
		Multiplier.Value = DataStore:GetAsync(Player.UserId..'_Multiplier') or 0
	end)
	
	if not success  then
		warn('DataStore: '..oops)
	end
end)

Players.PlayerRemoving:Connect(function(Player)
	local success, oops = pcall(function()
		DataStore:SetAsync(Player.UserId..'_Clicks', Player.leaderstats.Clicks.Value)
		DataStore:SetAsync(Player.UserId..'_Multiplier', Player.leaderstats.Multiplier.Value)
	end)
	
	if not success then
		warn('DataStore: '..oops)
	end
end)

--/ Enjoy!

I believe that should work, let me know if otherwise! :slightly_smiling_face:

Thats pretty much my script except without the BindToClose, which is crucial when working with DataStores.

You can try this.

local DataStoreService = game:GetService('DataStoreService')
local DataStore = DataStoreService:GetDataStore('Save_DataStore1')

Players.PlayerAdded:Connect(function(Player)

    -- Data Folder inside the Player instead of being inside leaderstats folder
	local  DataFolder = Instance.new('Folder')
	 DataFolder.Name = 'DataFolder'
	 DataFolder.Parent = Player
	
	local Clicks = Instance.new('IntValue', DataFolder)
	Clicks.Name = 'Clicks'
	
	local Multiplier = Instance.new('IntValue', DataFolder)
	Multiplier.Name = 'Multiplier'

	local playerkey = "id_"..player.UserId
	local data = playerDataStore:GetAsync(playerkey)
	if data then 
		Clicks.Value = data['Clicks']
		Multiplier.Value = data['Multiplier']
	else
		Clicks.Value = 0
		Multiplier.Value = 0
	end
end)

-- Creating Multiple Table Values
local function create_table(player)
	local player_stats = {}
	
	for _, stat in pairs(player.DataFolder:GetChildren()) do
		player_stats[stat.Name] = stat.Value
	end
	return player_stats

end

local function SaveData(player)
	print('Saving...')
	local playerkey = "id_"..player.UserId
	local player_stats = create_table(player)
	
	local success, err = pcall(function()
		playerDataStore:SetAsync(playerkey, player_stats)
	end)
	if success  then
		print('SUCCESSFULLY SAVED DATA!')
	else 
		print('FAILED TO SAVE THE DATA!')
	end
end

game.Players.PlayerRemoving:connect(function(player)
	SaveData(player)
end)

game:BindToClose(function()
	wait(5)
	for _, player in pairs(game.Players:GetPlayers()) do
		SaveData(player)
	end
end)

could prob save multiple datas

just create leaderstats folder again and make the same values and get the values from the datafolder

For Example:

game.Players.PlayerAdded:Connect(function(player)
	
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"
	
	local multipliers = Instance.new("IntValue", leaderstats)
	multipliers.Name = "Multipliers"
	
	local clicks = Instance.new("IntValue", leaderstats)
	clicks.Name = "Clicks"
	
	
	while wait() do
		wait(1)
		multipliers.Value = player.DataFolder.Multipliers.Value
	end
	
	while wait() do
		wait(1)
		clicks.Value = player.DataFolder.Clicks.Value
	end
	
end)

I recommend pre-constructing the leaderstats Folder.

Too many times have I seen people hard-code leaderstats. It’s horrible for readability. Pre-constructing the Folder will vastly clean up your program as it simplifies to a single Instance:Clone call. Modularity and visualization is also improved.

FYI, the Parent property of leaderstats should be the last one set.

I’d recommend looking at this tutorial.