Issue With Shop Saving

Hello Developers!

I’ve made a save script for my shop and it does work, but it causes lag and I’m not sure why. However, this wasn’t the case yesterday, so I’m not sure what the reason could be. I’m also experiencing Data Loss, but that was the case all along and didn’t start occuring today.

local Key = 10

local DataStore = game:GetService("DataStoreService"):GetDataStore("Tools")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ShopItems = require(ReplicatedStorage:WaitForChild("ShopItems"))

game.Players.PlayerAdded:Connect(function(player)
	
	local OwnedItemsFolder = Instance.new("Folder")
	OwnedItemsFolder.Name = "OwnedItems"
	OwnedItemsFolder.Parent = player
	
	local EquippedItemsFolder = Instance.new("Folder")
	EquippedItemsFolder.Name = "EquippedItems"
	EquippedItemsFolder.Parent = player
		
	for index, value in pairs(ShopItems.Swords) do
		
		local BoolValue = Instance.new("BoolValue")
		BoolValue.Name = index
		BoolValue.Parent = OwnedItemsFolder
		
		local BoolValue = Instance.new("BoolValue")
		BoolValue.Name = index
		BoolValue.Parent = EquippedItemsFolder
		
	end
	
	for index, value in pairs(ShopItems.Boosts) do
		
		local BoolValue = Instance.new("BoolValue")
		BoolValue.Name = index
		BoolValue.Parent = OwnedItemsFolder
		
		local BoolValue = Instance.new("BoolValue")
		BoolValue.Name = index
		BoolValue.Parent = EquippedItemsFolder
		
	end
	
	for index, value in pairs(ShopItems["Secondary Weapons"]) do
		
		local BoolValue = Instance.new("BoolValue")
		BoolValue.Name = index
		BoolValue.Parent = OwnedItemsFolder
		
		local BoolValue = Instance.new("BoolValue")
		BoolValue.Name = index
		BoolValue.Parent = EquippedItemsFolder
		
	end
	
	local succes, errormessage = pcall(function()
		
		for i, v in pairs(player.OwnedItems:GetChildren()) do
			
			local data = DataStore:GetAsync(player.UserId..Key..v.Name.."purchased", v.Value)
			if data ~= nil then
				player.OwnedItems[v.Name].Value = data
			elseif v.Name == "Sword" then
				player.OwnedItems[v.Name].Value = true
			else
				player.OwnedItems[v.Name].Value = false
			end
		end
		
		for i, v in pairs(player.EquippedItems:GetChildren()) do
			
			local data = DataStore:GetAsync(player.UserId..Key..v.Name.."equipped", v.Value)
			if data ~= nil then
				player.EquippedItems[v.Name].Value = data
			elseif v.Name == "Sword" then
				player.EquippedItems[v.Name].Value = true
			else
				player.EquippedItems[v.Name].Value = false
			end
			
		end
		
	end)
	
	if not succes then
		
		warn(errormessage)
		
	else
		
		print("Succes!")
		
	end
				
end)

game.Players.PlayerRemoving:Connect(function(player)
	
	local succes, errormessage = pcall(function()
		
		for i, v in pairs(player.OwnedItems:GetChildren()) do
			
			DataStore:SetAsync(player.UserId..Key..v.Name.."purchased", v.Value)
			
		end
		
		for i, v in pairs(player.EquippedItems:GetChildren()) do
			
			DataStore:SetAsync(player.UserId..Key..v.Name.."equipped", v.Value)
			
		end
		
	end)
	
	if not succes then
		
		warn(errormessage)
		
	else
		
		print("Succes!")
		
	end
	
end)

game:BindToClose(function()
	
	wait(5)
	
end)

I appreciate all help / feedback! Please let me know if you’ve found the issue and possibly how to fix it!

2 Likes

Here’s some more information regarding this issue. When someone joins the game, the GetAsync() value drops and then rises up slowly. I don’t know if this helps, but I hope it does!

Screenshot my friend made:

I am not sure, but as I understand, you are saving a key for every owned item. You can just save one key with a table of the owned and equip items. Maybe a lot of keys cause lag.

1 Like

I didn’t think about that, I’ll try to do that now!

1 Like

If this is returning more than 10 items which need saving, it’s likely to run into difficulties because of the limits on Set/GetAsyncs per minute with data stores.

Probably worth a read if you haven’t already:

1 Like

Hey, I noticed that you liked my post, did it work for you? And also, he is right, are you saving more than 10 items?

I just like every reply I get, I haven’t finished.

No, I’m only saving around 8 at the moment.

1 Like

I’m saving it with tables now, but I can’t think of a way to set the saved values to the correct BoolValues to load the data back in.

local Key = 12

local DataStore = game:GetService("DataStoreService"):GetDataStore("Tools")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ShopItems = require(ReplicatedStorage:WaitForChild("ShopItems"))

game.Players.PlayerAdded:Connect(function(player)
	
	local OwnedItemsFolder = Instance.new("Folder")
	OwnedItemsFolder.Name = "OwnedItems"
	OwnedItemsFolder.Parent = player
	
	local EquippedItemsFolder = Instance.new("Folder")
	EquippedItemsFolder.Name = "EquippedItems"
	EquippedItemsFolder.Parent = player	
	
	for i, v in pairs(ShopItems) do
		
		for p, g in pairs(v) do
			
			local BoolValue = Instance.new("BoolValue")
			BoolValue.Name = p
			BoolValue.Parent = OwnedItemsFolder
		
			local BoolValue = Instance.new("BoolValue")
			BoolValue.Name = p
			BoolValue.Parent = EquippedItemsFolder
			
		end
		
	end
	
	local ownedData = DataStore:GetAsync(player.UserId..Key.."-owned")	
	local equippedData = DataStore:GetAsync(player.UserId..Key.."-equipped")
	
	local succes, errormessage = pcall(function()
		
		for i, v in pairs(ownedData) do
			
			------------------------------------------ I want to load it in here.
			
		end
		
	end)
	
	if not succes then
		
		warn(errormessage)
		
	else
		
		print("Succes!")
		
	end
				
end)

game.Players.PlayerRemoving:Connect(function(player)
	
	local OwnedItemsTable = {}
	local EquippedItemsTable = {}
	
	for i, v in pairs(player.OwnedItems:GetChildren()) do
		
		table.insert(OwnedItemsTable, 1, v.Value)
		
	end
	
	for i, v in pairs(player.EquippedItems:GetChildren()) do
		
		table.insert(EquippedItemsTable, 1, v.Value)
		
	end
	
	local succes, errormessage = pcall(function()
		
		DataStore:SetAsync(player.UserId..Key.."-owned", OwnedItemsTable)	
		
		DataStore:SetAsync(player.UserId..Key.."-equipped", EquippedItemsTable)	
		
	end)
	
	if not succes then
		
		warn(errormessage)
		
	else
		
		print("Succes!")
		
	end
	
end)

game:BindToClose(function()
	
	wait(5)
	
end)
1 Like

I am going to try something with this script, if it works, I’ll post it here just a second.

1 Like

Try this:

local Key = 12

local DataStore = game:GetService("DataStoreService"):GetDataStore("Tools")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ShopItems = require(ReplicatedStorage:WaitForChild("ShopItems"))

game.Players.PlayerAdded:Connect(function(player)
	
	local OwnedItemsFolder = Instance.new("Folder")
	OwnedItemsFolder.Name = "OwnedItems"
	OwnedItemsFolder.Parent = player
	
	local EquippedItemsFolder = Instance.new("Folder")
	EquippedItemsFolder.Name = "EquippedItems"
	EquippedItemsFolder.Parent = player	
	
	for i, v in pairs(ShopItems) do
		
		for p, g in pairs(v) do
			
			local BoolValue = Instance.new("BoolValue")
			BoolValue.Name = p
			BoolValue.Parent = OwnedItemsFolder
		
			local BoolValue = Instance.new("BoolValue")
			BoolValue.Name = p
			BoolValue.Parent = EquippedItemsFolder
			
		end
		
	end
	
	local ownedData
	local equippedData
	
	local succes, errormessage = pcall(function()
		
		ownedData = DataStore:GetAsync(player.UserId..Key.."-owned")

		equippedData = DataStore:GetAsync(player.UserId..Key.."-equipped")		
		
		
	end)
	if(succes) then
		for name, value in pairs(ownedData) do
			local object = OwnedItemsFolder:FindFirstChild(name)
			if(object) then
				object.Value = value
			end
		end
		for name, value in pairs(equippedData) do
			local object = EquippedItemsFolder:FindFirstChild(name)
			if(object) then
				object.Value = value
			end
		end
		print("Data loaded successfully!")
	else
		print("Error loading data:")
		warn(errormessage)
	end		
end)

game.Players.PlayerRemoving:Connect(function(player)
	
	local OwnedItemsTable = {}
	local EquippedItemsTable = {}
	
	for i, v in pairs(player.OwnedItems:GetChildren()) do
		
		OwnedItemsTable[v.Name] = v.Value
		
	end
	
	for i, v in pairs(player.EquippedItems:GetChildren()) do
		
		EquippedItemsTable[v.Name] = v.Value
		
	end
	
	local succes, errormessage = pcall(function()
		
		DataStore:SetAsync(player.UserId..Key.."-owned", OwnedItemsTable)	
		
		DataStore:SetAsync(player.UserId..Key.."-equipped", EquippedItemsTable)	
		
	end)
	
	if not succes then
	
		print("Error saving data:")
		warn(errormessage)
		
	else
		
		print("Saved Successfully!")
		
	end
	
end)

game:BindToClose(function()
	
	wait(5)
	
end)

I am not 100% sure that will work. But worth a try. That’s how I save tables.
Basically, the value name place in the table is the value, and we load it by checking if the name exists in the folder, and if it is, give it a value.

It works very well! Thank you so much!

1 Like