Shop giving you amount of swords corresponding to amount off players bug

What I’m trying to do here is script a shop UI where if you purchase or equip a sword, you receive ONE item at once. However there is this super weird bug that I can’t seem to figure out why or how it happens. If there is 2 players in a server, and a player walks up to purchase a sword, they will receive (singularly) 2 swords. If there is 3 players, then a player buys a sword, they will receive 3 swords etcetera.

Here is how I have it set up:

Starter GUI


Script Parented to ShopGUI

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")

local buySwordEvent = ReplicatedStorage.Remotes.BuySword

local SwordCost = require(ReplicatedStorage.Modules.SwordCost)
local SwordsInOrder = require(script.SwordsInOrder)

local swords = ServerStorage.Swords

local function onButtonActivated(player, swordName)
	local cost = SwordCost[swordName]
	local coins = player:WaitForChild("leaderstats"):WaitForChild("Coins")
	local swordsOwnedFolder = ServerStorage.RemoteData:WaitForChild(player.Name):WaitForChild("SwordsOwned")
	local swordOwned = swordsOwnedFolder:WaitForChild(swordName)
	
	local index = table.find(SwordsInOrder, swordName)
	
	local lastIndex = index - 1
	local lastKey = SwordsInOrder[lastIndex]
	
	if coins.Value >= cost then
		if swordOwned.Value == true then			
			local sword = swords[swordName]:Clone()
			sword.Parent = player.Backpack
		elseif swordsOwnedFolder[lastKey].Value == true and lastKey ~= nil then
			local newValue = SwordsInOrder[index]
			swordsOwnedFolder[newValue].Value = true
			
			coins.Value = coins.Value - cost
			
			local sword = swords[swordName]:Clone()
			sword.Parent = player.Backpack
		end
	end
end

buySwordEvent.OnServerEvent:Connect(onButtonActivated)

SwordsInOrder Module Script Parented to Script

local swordsInOrder = {"TreeBranch", "RustyBlade", "HardenedWoodenBlade", "ModernKnife", "MilitaryKnife"}
return swordsInOrder

LocalScript Parented to ShopGUI

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage.Remotes.BuySword

Instance.new("Script", script.Parent.Parent)

local textButton = {}

for i, v in pairs(script.Parent.Frame.ScrollingFrame:GetChildren()) do
	local button = v:FindFirstChildWhichIsA("TextButton")
	if button then
		table.insert(textButton, i, button)
	end
end

for i, v in pairs(textButton) do
	v.Activated:Connect(function()
		local name = v.Name
		remoteEvent:FireServer(name)
	end)
end

SwordCost parented to Modules inside of ReplicatedStorage

local swordCosts = {
	TreeBranch = 30;
	RustyBlade = 40;
	HardenedWoodenBlade = 50;
	ModernKnife = 60;
	MilitaryKnife = 70;
}

return swordCosts

leaderstats script in ServerScriptService

local ServerStorage = game:GetService("ServerStorage")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

--local function 

Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local coins = Instance.new("NumberValue")
	coins.Name = "Coins"
	coins.Parent = leaderstats
	
	local kills = Instance.new("NumberValue")
	kills.Name = "Kills"
	kills.Parent = leaderstats
	
	local wins = Instance.new("NumberValue")
	wins.Name = "Wins"
	wins.Parent = leaderstats
	
	local dataFolder = Instance.new("Folder")
	dataFolder.Name = player.Name
	dataFolder.Parent = ServerStorage.RemoteData
	
	local swordsOwned = Instance.new("Folder")
	swordsOwned.Name = "SwordsOwned"
	swordsOwned.Parent = dataFolder
	
	for i, sword in pairs(ServerStorage.Swords:GetChildren()) do
		local swordValue = Instance.new("BoolValue")
		swordValue.Name = sword.Name
		if swordValue.Name == "TreeBranch" then
			swordValue.Value = true
		end
		swordValue.Parent = swordsOwned
	end
	
	local swingHandlningDebounce = Instance.new("BoolValue")
	swingHandlningDebounce.Name = "SwingHandlingDebounce"
	swingHandlningDebounce.Parent = dataFolder
	
	local ownsSword = Instance.new("BoolValue")
	ownsSword.Name = "OwnsSword"
	ownsSword.Parent = player
end)

If anyone can help that would be greatly appreciated :grinning:

Edit: here is a download of the shop
Roblox Shop Example.rbxl (36.7 KB)

1 Like

After heaps of testing, I found the issue was really weird, all I had to do was move the server script that was originally inside of the tool, and copy and paste it into ‘ServerScriptService’, then it just fixed itself lol, no idea how that works.

Yeah the reason this was happening was because it was in the shopgui that means their were as many shop scripts as their were players, and since they all listen to the remote event they would all fire which gave you multiple purchases. Since you moved it to the serverstorage there is now only one listener. Glad you were able to figure out the problem I thought explaining why would give clarity and help later on down the road

1 Like

Yes thank you this helped me understand!