Saving Data from Previous Sessions

Hi! So this is not regarding leaderstats data but saving data from previous sessions. Allow me to explain. If a player has a title equipped and they leave, the next time they join, the same title should be located on their avatar. Another example would be pets. If a player has a pet equipped, the next time they join, the pet should already be sitting next to their avatar.

So I am using this script in serverscriptservice to create leaderstats and values. In the script, it creates the values previousstyle and previoustitle. I want previoustitle to equal the text on top of the character’s head and then save that value when the player leaves. Here is my script:

function saveData(plrLeaving)

	local ownedTools = {}
	for i, tool in pairs(plrLeaving.OwnedTools:GetChildren()) do
		table.insert(ownedTools, tool.Name)
	end
	local ownedTitles = {}
	for i, title in pairs(plrLeaving.OwnedTitles:GetChildren()) do
		table.insert(ownedTitles, title.Name)
	end
	

	local success, err = pcall(function()
		ds:SetAsync("titles-" .. plrLeaving.UserId, ownedTitles)
		ds:SetAsync("tools-" .. plrLeaving.UserId, ownedTools)
		ds:SetAsync("coins-" .. plrLeaving.UserId, plrLeaving.leaderstats.Coins.Value)
		ds:SetAsync("wins-" .. plrLeaving.UserId, plrLeaving.leaderstats.Wins.Value)
		ds:SetAsync("skips-" .. plrLeaving.UserId, plrLeaving.leaderstats.Skips.Value)

	end)
end

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

	
	local toolsOwned = {}
	local titlesOwned = {}
	local style = ""
	local title = ""
	local coins = 0
	local wins = 0
	local skips = 0
	pcall(function()
		titlesOwned = ds:GetAsync("titles-" .. plr.UserId) or {}
		toolsOwned = ds:GetAsync("tools-" .. plr.UserId) or {}
		coins = ds:GetAsync("coins-" .. plr.UserId) or 0
		title = ds:GetAsync("title-" .. plr.Character.Head.NameTag.Title.Text) or ""
		style = ds:GetAsync("style-" .. plr.UserId) or ""
		wins = ds:GetAsync("wins-" .. plr.UserId) or 0
		skips = ds:GetAsync("wins-" .. plr.UserId) or 0
	end)




	local ls = Instance.new("Folder", plr)
	ls.Name = "leaderstats"

	local coinsValue = Instance.new("IntValue", ls)
	coinsValue.Name = "Coins"
	coinsValue.Value = coins

	local winsValue = Instance.new("IntValue", ls)
	winsValue.Name = "Wins"
	winsValue.Value = wins

	print(skips)


	local skipsValue = Instance.new("IntValue", plr)
	skipsValue.Name = "Skips"
	skipsValue.Value = skips
	
	
	local previoustitle = Instance.new("StringValue", plr)
	previoustitle.Name = "previoustitle"
	previoustitle.Value = title

	local previousstyle = Instance.new("StringValue", plr)
	previousstyle.Name = "previousstyle"
	previousstyle.Value = style
	
	plr.CharacterAdded:Connect(function(char)
		--Varibles
		local head = char.Head
		local newtext = nametag:Clone() 
		local uppertext = newtext:WaitForChild("Name")
		local lowertext = newtext.Title
		local humanoid = char.Humanoid

		humanoid.DisplayDistanceType = "None"

		--Main Text
		newtext.Parent = head
		newtext.Adornee = head
		uppertext.Text = plr.Name 
		
		if plr.previoustitle.Value ~= "" then
			lowertext.Text = plr.previoustitle.Value
		end

		--"If" Statements
		--You can add as many of these as you wish, just change it to the player's name.

	end)



	



	local ownedFolder2 = Instance.new("Folder", plr)
	ownedFolder2.Name = "OwnedTools"
	
	local ownedFolder3 = Instance.new("Folder", plr)
	ownedFolder3.Name = "OwnedTitles"



	for i, owned in pairs(toolsOwned) do

		if tools:FindFirstChild(owned) then

			tools[owned]:Clone().Parent = ownedFolder2
		end
	end
	
	for i, owned in pairs(titlesOwned) do

		if titles:FindFirstChild(owned) then

			titles[owned]:Clone().Parent = ownedFolder3
		end
	end
	
end)












game.Players.PlayerRemoving:Connect(saveData)

game:BindToClose(function()

	for i, plrLeaving in pairs(game.Players:GetPlayers()) do
		saveData(plrLeaving)
	end
end)

The player’s title is not saving to the value and/or it is not loading correctly. What can I do to fix this?

2 Likes

I am still having this issue at the moment.

1 Like

A lot of games have this, im just wondering how I can implement this.

1 Like

save previoustitle then, you already have the value

Where would I save it, in plrleaving?

I changed my script up a bit but it still doesn’t work.

Is anybody able to help me with this?

You don’t have to use SetAsync/GetAsync 5 trillion times. Make sure to Save the data inside a Table, use a single UpdateAsync with

local data = GAME_DS:UpdateAsync(DS_KEY.."/"..plr.UserId,function()
						return tableToSave
					end)

And load the data from the table with a single GetAsync

When a player is going to leave, create a table of all things you want to save.

local save = {
    ["titleEquipped"] = "the title here",
    ["petEquipped"] = "the pet currently equipped" 
}

After you create this table, save it in a datastore with the id of the player. Now, you can just load the data you have saved earlier and then it would load a table, read that table and load each data inside it. And then, you can just set each data (equipped items) for the player with a script

I am genuienly so confused on how to do this. I tried my best but there are some errors. Please look at my script and see what I can do to fix this. I am trying to save the table but I have no clue how to save it when the player is leaving and how to set a cloned value to a value inside of the table (previoustitle). Here is the script I am using currently (it doesn’t work):

function saveData(plrLeaving)

	local ownedTools = {}
	for i, tool in pairs(plrLeaving.OwnedTools:GetChildren()) do
		table.insert(ownedTools, tool.Name)
	end
	local ownedTitles = {}
	for i, title in pairs(plrLeaving.OwnedTitles:GetChildren()) do
		table.insert(ownedTitles, title.Name)
	end
	local previous = {}
	for i, title in pairs(plrLeaving.previous:GetChildren()) do
		table.insert(previous, title.Name)
	end
	

	local success, err = pcall(function()
		ds:SetAsync("titles-" .. plrLeaving.UserId, ownedTitles)
		ds:SetAsync("save-" .. plrLeaving.UserId, previous)
		ds:SetAsync("tools-" .. plrLeaving.UserId, ownedTools)
		ds:SetAsync("coins-" .. plrLeaving.UserId, plrLeaving.leaderstats.Coins.Value)
		ds:SetAsync("wins-" .. plrLeaving.UserId, plrLeaving.leaderstats.Wins.Value)
		ds:SetAsync("skips-" .. plrLeaving.UserId, plrLeaving.leaderstats.Skips.Value)

	end)
end

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

	local save = {}
	local toolsOwned = {}
	local titlesOwned = {}
	local coins = 0
	local wins = 0
	local skips = 0
	pcall(function()
		titlesOwned = ds:GetAsync("titles-" .. plr.UserId) or {}
		toolsOwned = ds:GetAsync("tools-" .. plr.UserId) or {}
		coins = ds:GetAsync("coins-" .. plr.UserId) or 0
		save = ds:GetAsync("save-" .. plr.UserId) or {}
		wins = ds:GetAsync("wins-" .. plr.UserId) or 0
		skips = ds:GetAsync("wins-" .. plr.UserId) or 0
	end)




	local ls = Instance.new("Folder", plr)
	ls.Name = "leaderstats"

	local coinsValue = Instance.new("IntValue", ls)
	coinsValue.Name = "Coins"
	coinsValue.Value = coins

	local winsValue = Instance.new("IntValue", ls)
	winsValue.Name = "Wins"
	winsValue.Value = wins

	print(skips)


	local skipsValue = Instance.new("IntValue", plr)
	skipsValue.Name = "Skips"
	skipsValue.Value = skips
	
	local p = Instance.new("Folder", plr)
	p.Name = "previous"
	
	local previoustitle = Instance.new("StringValue", p)
	previoustitle.Name = "previoustitle"
	previoustitle.Value = table.find(save, "titleEquipped")

	local previousstyle = Instance.new("StringValue", p)
	previousstyle.Name = "previousstyle"
	
	
	plr.CharacterAdded:Connect(function(char)
		--Varibles
		local head = char.Head
		local newtext = nametag:Clone() 
		local uppertext = newtext:WaitForChild("Name")
		local lowertext = newtext.Title
		local humanoid = char.Humanoid

		humanoid.DisplayDistanceType = "None"

		--Main Text
		newtext.Parent = head
		newtext.Adornee = head
		uppertext.Text = plr.Name 
		
		if plr.previous:WaitForChild(previoustitle).Value ~= "" then
			lowertext.Text = plr.previous.previoustitle.Value
		end

		--"If" Statements
		--You can add as many of these as you wish, just change it to the player's name.

	end)



	



	local ownedFolder2 = Instance.new("Folder", plr)
	ownedFolder2.Name = "OwnedTools"
	
	local ownedFolder3 = Instance.new("Folder", plr)
	ownedFolder3.Name = "OwnedTitles"



	for i, owned in pairs(toolsOwned) do

		if tools:FindFirstChild(owned) then

			tools[owned]:Clone().Parent = ownedFolder2
		end
	end
	
	for i, owned in pairs(titlesOwned) do

		if titles:FindFirstChild(owned) then

			titles[owned]:Clone().Parent = ownedFolder3
		end
	end
	
end)

maybe first of all you can start with showing the errors in the console that you face with, so we can deal with them

None of the values or folders, like leaderstats, are cloning to the player which means there is some error in the script that isn’t working. It’s also causing an infinite yield at seperate scripts that are trying to find the folders that are not being duplicated. The problem with scripts like this in serverscriptservice is that it doesn’t show the error in the output.

can you add prints to end and starting of these lines and after running it, can you share console result to us?

1 Like

Narrowed it down to these:

local skipsValue = Instance.new("IntValue", plr)
	skipsValue.Name = "Skips"
	skipsValue.Value = skips
	
	local p = Instance.new("Folder", plr)
	p.Name = "previous"
	
	local previoustitle = Instance.new("StringValue", p)
	previoustitle.Name = "previoustitle"
	previoustitle.Value = table.find(save, "titleEquipped")

	local previousstyle = Instance.new("StringValue", p)
	previousstyle.Name = "previousstyle"

It is most likely to do with this line:

previoustitle.Value = table.find(save, "titleEquipped")

I don’t know what to change.

i thought you said it have problem with creating folders, so i think we should focus on that issue firstly and we can fix other issues after fixing that.

so can you try what i suggested first?

My problem was never creating folders. Its loading and saving a table with values inside just like TheLordGamer1820 showed me.

Also, I did what you suggested and narrowed down the issue with print statements.

i did not understand well, but if you don’t have problem with this, what exactly your problem is?

Yes, the cloning problem will be fixed if the error in the script is fixed. The cloning was fine before I started trying to make a table with values inside that is loaded and saved correctly.

The problem is that I have no idea how to create, load, and save a table with values inside just like TheLordGamer1820 said in this post.

Okay, so correct me, do your problem is learning how to make DataStore save and load with table values?