What's wrong with my script?

  1. What do you want to achieve?
    I have created a shop GUI that is triggered by a ProximityPrompt that gives the player a tool from ServerStorage when they click on a text button; however, when they click on the button, the tool isn’t given to them.

  2. What is the issue?
    The money is removed from the player’s leaderstats; however, the tool isn’t given to them.

  3. What solutions have you tried so far?
    I tried using a shop for another game as a reference; however, for that system, it’s just a part with a click detector—in this game, it’s a GUI button. I’ve tried looking up other shop GUI tutorials online; however, they’re using ReplicatedStorage instead of ServerStorage (I’m trying to use ServerStorage).

Here’s the layout of the Explorer & my GUI Button scripts:
Button Explorer Layout
“VBear” is the specific button I’m using as an example
Screen Shot 2022-07-27 at 11.23.45 AM
ToolGiver LocalScript

local player = game.Players.LocalPlayer
local folder = game:GetService("ServerStorage"):FindFirstChild("Food")
local subFolder = folder:FindFirstChild("Cafe")
local icecream = game.ServerStorage.Food.Cafe["Ice Cream"]
local backpack = player.Backpack

script.Parent.MouseButton1Click:Connect(function()
	local newicecream = icecream:Clone()
	newicecream.Parent = backpack
end)

MoneyLocalScript

local debounce = false
script.Parent.MouseButton1Click:Connect(function()
	if not debounce then
		debounce = true
		game.ReplicatedStorage.TakeCash:FireServer()
		wait(0.1)
		debounce = false
	end
end)

ServerStorage Layout
Screen Shot 2022-07-27 at 11.15.13 AM
ReplicatedStorage Layout
Screen Shot 2022-07-27 at 11.27.20 AM

Let me know if there is any more information I can give to you to help figure out my issue :slight_smile: Thank you!

1 Like

First for the Money script

local player = game.Players.LocalPlayer
local debounce = false
script.Parent.MouseButton1Click:Connect(function()
	if not debounce then
		debounce = true
		player.leaderstats.Money.Value -= "whatever amount"
		wait(0.1)
		debounce = false
	end
end)

for the toolgiver:
you’ll have to fire a server event and then put the tool in the backpack

2 Likes

How would I create a Server Event for the tool?

From my understanding, I’d have to trigger an RE and connect it to a script in ServerScriptService … but how would I write the ServerScript in ServerScriptService?

I have multiple tools in my game so I don’t want to create an RE & a ServerScript for each one.

Basically you’d make a remote event that accepts the tool’s name as an argument. On the server, you’d find the tool from its name and give it accordingly.

1 Like

You can’t access ServerStorage and ServerScriptService via LocalScripts. Also as this script is local effects will be local. Given tool will be local (no other players will see it) and changes to the map will be local. LocalScripts are made expecially for gui’s that are local. To manage players (to give tools, teleport, give money, etc.) use server Scripts. Communicate between server and clients by RemoteEvents.

2 Likes

the script would basically be like this

game.ReplicatedStorage["whatever the name is"].OnServerEvent:Connect(function(plr, toolname)
if toolname == "VBear" then
local ic = game.ServerStorage.Food:WaitForChild("Ice Cream"):Clone()
ic.Parent = plr.Backpack
end
end)
1 Like

May you go into more depth about how I would go about doing so?

I’m quite new to scripting so I don’t have the best knowledge about these things.

So on your client you would fire the remote event with the name of the tool:

RemoteEvent:FireServer("Lemonade")

Then you would have to handle it on the server:

RemoteEvent.OnServerEvent:Connect(function(player,toolName)
  local Tool = ServerStorage:FindFirstChild(toolName)
  if Tool then
    Tool:Clone().Parent = player.Backpack
  end
end)

This would be the most simplified way of doing it.

1 Like

Would that be the script within the GUIButton?

Would I have to create a ServerScript as well? Or would I just have to create an RE?

you would fire the server through the local script
and play the event through a server script

1 Like

The first script (simplified, undefined variables) would be the script used by the button, the second script would go in ServerScriptService as a “Script” and handle the remote event.

1 Like

Do I have to create an RE for every tool name & a ServerScript for every tool with this method? So an RE named “Ice Cream” and another named “Chocolate Ice Cream” and then separate ServerScripts in ServerScriptStorage like:

["Ice Cream"].OnServerEvent:Connect(function(player, "Ice Cream")
  local Tool = ServerStorage:FindFirstChild("Ice Cream")
  if Tool then
    Tool:Clone().Parent = player.Backpack
  end
end)
["Chocolate Ice Cream"].OnServerEvent:Connect(function(player, "Chocolate Ice Cream")
  local Tool = ServerStorage:FindFirstChild("Chocolate Ice Cream")
  if Tool then
    Tool:Clone().Parent = player.Backpack
  end
end)

What you should do is create a single remote event called “GiveTools” and then you bind that one event using the code I shared for the most part.

1 Like

Let me try out your instructions and then I’ll check with you if I’m doing it right!

Okay, here’s what I’ve got:

I’ve put an RE in ReplicatedStorage named “GiveTool”

GUIButton Script:

script.Parent.MouseButton1Click:Connect(function()
	game.ReplicatedStorage.GiveTool:FireServer("Ice Cream")
end)

Then I placed a Script in ServerScriptStorage named “GiveToolScript”

local GiveTool = game.ReplicatedStorage
ServerStorage = game.ServerStorage
GiveTool.OnServerEvent:Connect(function(player, toolName)
	local Tool = ServerStorage.Food.Cafe:FindFirstChild(toolName)
	if Tool then
		Tool:Clone().Parent = player.Backpack
	end
end)

Is this how I would do it?

If I were to use the same script for multiple tools would I write:

game.ReplicatedStorage["GiveTool"].OnServerEvent:Connect(function(plr, toolname)
if toolname == "VBear" then
local ic = game.ServerStorage.Food.Cafe:WaitForChild("Ice Cream"):Clone()
ic.Parent = plr.Backpack

if toolname == "CBear" then
local ic = game.ServerStorage.Food.Icecream:WaitForChild("C Ice Cream"):Clone()
ic.Parent = plr.Backpack

--etc. etc.
end
end)

?

I see. So the scripts inside my buttons should be ServerScripts, not LocalScripts?

UI is local (only currect player see and cointrols it) and it should be controlled by the LocalScript (server Scripts will not work). You want to buy something for example: You got a UI with displayed product and button to buy it. LocalScript catches a click and sends an informations (what product to buy) to server via RemoteEvent/RemoteFunction. Server Script verifies it and if player can buy it then changes the balance and gives player the bought thing.

1 Like