Trouble with a Data Store duplicating certain items

I’m working on a tycoon type game, and am using a Data Store for recording a player’s progress (money & Workspace content).

The issue I’m having is with the data store for a player’s progress into a tycoon. My system right now works like this:

Upon leaving or manually saving progress, the data store used only for a player’s progress into their tycoon saves all the names of objects currently in the player’s Workspace tycoon folder. Then upon re-entering and touching the start gate for a tycoon, the gate checks for the data, finds the matching names in that specific tycoon slot’s server storage folder, and clones it back into Workspace.

Every item has a unique name, and all buttons used for making purchases have the word “Button” in the name, along with a unique letter at the end to differentiate. I use a string find function to correctly separate these objects into their folders as they spawn back in, no problems thus far.

But for what ever reason, I am consistently having an issue with this duplicating or double saving certain objects, which ends up double-charging a player for an upgrade if a button happens to be doubled. I can see through print statements what my save function saves, and even when it correctly saves only a single entry for every instance, the load feature will randomly duplicate items on re-enter.

This is the portion responsible for loading a player’s content in after starting a tycoon, I’ve added comments to help clarify:

plrData = DataT:GetAsync(prefix  .. tostring(lookupPlayer.UserId))

	if plrData then
	stopLoading = true
	print("plrData has been found.")

	ownerEnab.Value = true
		slot.Value = UniqueTycoonNumber
	sssPlayerFolder.MoneyTick.Disabled = false

	local ownerStringName = Instance.new("StringValue",script.Parent.Parent)
		ownerStringName.Value = playerName
		ownerStringName.Name = "OwnerStringName"
	--local firstButton = script.Parent.Parent.Buttons.FirstButton --delete this before release. for debugging
	--firstButton.ClickDetector.MaxActivationDistance = 32
		for i, v in pairs(plrData) do
			print(i, v)
			tycoonProg = v -- the only thing saved to this data store is a table with the names of a player's owned tycoon objects
			tycoonTable = {}
			for i = 1, #tycoonProg do
				local child = tycoonProg[i]
				table.insert(tycoonTable, child) --this populates a table with the contents of the saved data store table names
			end
		end
		local storageScan = ServerStorage[("Tycoon" .. plyTycoonSlot)]:GetDescendants()
		for i = 1, #storageScan do
			for c = 1, #tycoonTable do
				local dataChild = tycoonTable[c] --all string names pulled from the data store
				local servChild = storageScan[i] --all possible string names in a given tycoon, to be referenced
			if servChild.Name == dataChild then
				print("A child in ServerStorage was found.")
				local cloneChild = servChild:Clone()
				local findScripts = cloneChild:GetDescendants()
					for s = 1, #findScripts do
						local scriptChild = findScripts[s]
						if scriptChild.ClassName == "Script" then
							scriptChild.Disabled = false
						end
					end
						cloneChild.Parent = game.Workspace[("Tycoon" .. plyTycoonSlot)].SpawnObjects --by default, clones all found content into this folder first
						local buttonString = "Button"
						local blockerString = "Blocker"
						if cloneChild.Name:find(buttonString) then
							local buttonChild = cloneChild
							buttonChild.Parent = game.Workspace[("Tycoon" .. plyTycoonSlot)].Buttons --then finds anything with the word "Button" in its name, moving it to the button folder
						elseif cloneChild.Name:find(blockerString) then
							local blockerChild = cloneChild
							blockerChild.Parent = game.Workspace[("Tycoon" .. plyTycoonSlot)].Blocker --same as with the buttons folder, but with the word "Blocker"
						end	
			end
			end
		end
	destroyDoor()
	end
	end
loadCount = 0
end
script.Parent.Touched:Connect(loadTycoon)

It’s with that portion where things are getting double cloned, but I have no idea why. I’m still inexperienced with data stores, so am I doing something incorrectly, or not following best practice?

Additionally, this is a separate script for a gui manual save button that saves to the same DataT data store:

local tycoonProgress = {}
	local plyTycoon = game.Workspace:FindFirstChild("Tycoon" .. plySlotInt)
	local spawnObjFolder = plyTycoon.SpawnObjects:GetChildren()
	local buttonFolder = plyTycoon.Buttons:GetChildren()
	local blockerFolder = plyTycoon.Blocker:GetChildren()

	for i = 1, #spawnObjFolder do
		local child = spawnObjFolder[i].Name
		table.insert(tycoonProgress, child)
	end
	for i = 1, #buttonFolder do
		local child = buttonFolder[i].Name
		print(child, "part of all button children.")
		table.insert(tycoonProgress, child)
	end
	for i = 1, #blockerFolder do
		local child = buttonFolder[i].Name
		table.insert(tycoonProgress, child)
	end

	DataT:SetAsync(prefix .. tostring(player.UserId),{tycoonProgress})
	
	wait(5)
	--tycoonProgress = {}

	for i,v in ipairs(tycoonProgress) do
		print(i,v)
	end
	print("Player physical tycoon data has been saved.")
end

saveProg.OnServerEvent:connect(savePlayerProgress)

Even with confirming instances have only been saved once each with the manual save print statements (and no save on leave), and confirming there aren’t double instances in a tycoon’s server storage folder, I am still experiencing the random duplicating issue upon loading. Any help at all is greatly appreciated.

2 Likes