Remote Event Parameters

I am trying to make code for an item shop which will give you the sword you bought/equipped during the round. So first could you let me know if I am doing this wrong.

Basically the player has a bool value inside a folder which contains the item they bought. If it is true it means they have it. And then there is a string value which contains the item equipped.

The problem starts at the shop. The process of giving the sword works fine. When the player wants to buy the sword and click on it it fires a remote event with 3 parameters (I think that is what they are called correct me if I am wrong)

local player = game.Players.LocalPlayer

script.Parent.EmeraldSword.MouseButton1Click:Connect(function()
	if player.pointFolder.Points.Value >= 3000 then
		if player.weaponFolder.emSword.Value == false then
			local value = 3000
			local sword = "EmeraldSword"
			game.ReplicatedStorage.BuySword:FireServer(player, value, sword)
		else
			
		end

	else
		
	end
end)

Here is the server script.

game.ReplicatedStorage.BuySword.OnServerEvent:Connect(function(player, pointValue, sword)
	player.Equipped.Value = sword
	player.pointFolder.Points.Value = player.pointFolder.Points.Value - pointValue.Value
	player.weaponFolder.emSword.Value = true
end)

For some reason, the pointValue is getting an error and I think the sword one will too. (player works fine) I don’t know why this is happening. Did I not learn something right? I don’t know.

3 Likes

When firing a server event with a remote event you don’t have to send the player value, that’s sent automatically. You’re setting setting in your serverscript player to the player, but you’re also setting value to the player.

Change this line

game.ReplicatedStorage.BuySword:FireServer(player, value, sword)

to this

game.ReplicatedStorage.BuySword:FireServer(value, sword)

As well, you should also redo the checks on the server to see if the player owns the sword already and if they have enough points to buy it.

Example for checking if the player has enough points:

game.ReplicatedStorage.BuySword.OnServerEvent:Connect(function(player, pointValue, sword)
	if player.pointFolder.Points.Value >= pointValue then
		player.Equipped.Value = sword
		player.pointFolder.Points.Value = player.pointFolder.Points.Value - pointValue.Value
		player.weaponFolder.emSword.Value = true
	end
end)
11 Likes

When u are fireing server u shouldnt inculde player, because that is an defoult argument. so what happens when u are picking it up on the server? - u have two parameters equal to the player; player and pointValue

4 Likes

Ok thanks. I never learned that I don’t know why.

Edit: Should it work now? And for the future, is this the best way to make a shop?

You should be validating the player’s currency on the server,

if this is to check whether a player owns an item, then try to not use several value objects and instead either check whether it exists under player.StarterGear or have a table containing all owned tools, and insert into it from a DataStore too if you have to- this removes the dependency of having so many objects.

I also noticed your LocalScript contains empty else blocks, and this logic is flawed:

because even if a player had way more than 3000, it would pass the player’s value as 3000 regardless.

If you’ve got several Gui buttons for your shop, don’t just duplicate the same script changing the arguments, instead create a folder for all purchase buttons and use a loop of some sort to go through all of them, and whenever a buttons is clicked pass the name of the button, which should correspond to all existing tools.

A simple system you could implement

 local RS = game:GetService("ReplicatedStorage")
 local storage = game:GetService("ServerStorage").ToolsFolder
 local deb = {}
 local cooldown = 2

 RS.BuySword.OnServerEvent:Connect(function(player, swordName)
        if os.time() - (deb[player.Name] or 0)  > cooldown
        then deb[player.Name] = os.time()
      

        if storage:FindFirstChild(swordName) then
        local tool = storage[swordName]:Clone()
        local points = player.pointFolder.Points
        local _, last = string.find(tool.Name, "price:") 
        local price = tonumber(string.sub(tool.Name, last  + 1))
        if points.Value >= price then
        points.Value = points.Value - price
        tool.Parent = player.StarterGear
        tool.Parent = player.Backpack
        -- till here, the player's currency would have been subtracted
        -- and the tool cloned, I don't really understand what you're doing below this

	    player.Equipped.Value = swordName
  	    player.weaponFolder.emSword.Value = true
        end
    end
  end
end)
2 Likes

Ok, how should I make a table for all the tools in the DataStore? Btw I don’t want it to be cloned to the starter pack. The tool is only given during the round so I use a value.

Edit: If you want could we continue this in dms?

Round Script