I have a tool that I use for the shop in my game. Now the problem is that when I put my tool in Replicated Storage and clone the tool into workspace, the tool is invisible. When I put the tool in workspace and pick it up into my inventory, it doesn’t happen. Could anybody explain why and how to fix it?
Alright so tools need changes on the server to be done or it won’t weld to the character, won’t be seen, and changes won’t replicate to other clients. You need to use a server script for the actual cloning of the tool into the backpack/inventory, because otherwise filtering enabled will break things.
LocalScript seems unsafe, because those scripts will be tampered by exploiters eventually. Proper FE scripting is required for the cloning, if the tool needs to be seen client-sided.
Make sure the script is not placed in ReplicatedStorage. Because they won’t run and will never run there.
Consider using an ordinary script and clone it from ServerStorage. Because ReplicatedStorage will stress the network if you try to do it from there.
If you’re still considering the local script, post your code here. I believe it is an error within.(also test the tool again by re-equipping it)
What do you mean by this? Scripts in-game are RobloxLocked which means they cannot be viewed or modified by users who intend to do so (unless it uses loadstring, which is a different story). These scripts cannot be tampered, otherwise there would be chaos.
What? The cloning and parenting of a tool is a very very minor addition to the network load. If you do it through ReplicatedStorage using a LocalScript, that load is on the client. If you do it with a server script and clone the tool through ServerStorage, that load will be on the server.
In the future when making statements like these please back them up with proof or a credible source and ensure they are factual.
This is very poor practice because you are trusting the client to make a decision on whether or not the client itself has enough money to buy something. This if statement is essentially locking a door and leaving the key there for anyone to open. All an exploiter has to do is run the following line of code in their exploit:
They now have 99999999 cash, and because you have a LocalScript checking if they have enough cash, of course they do!
Any changes an exploiter makes (such as editting a leaderboard to give themselves money) are client sided, and so the server and all other players do not see that change happen. That change is solely visible on the exploiters screen. In order to prevent abuse of this, you should handle ALL calculations and checks of whether or not the player can do something on the server. This way, if a player does exploit and give themselves the cash needed to buy something, that change is not visible to the server, the server only sees cash that was legitimately awarded by the game, and so the server declines the player’s request to buy the item. On top of this, do not store the prices of items client-side, as the client can modify an item to cost whatever they want, even 0 Cash! A better way of doing this could be to create a folder in ServerStorage called ‘ShopItems’. Inside this folder would be another Folder with the item name, and inside that folder you would have an IntValue called ‘Price’, with its value set to the price that you want the item to have. For example:
You can do this verification to see if a player can buy something through RemoteFunctions.
Client
local leaderboard = player:WaitForChild("leaderstats")
local button = script.Parent
local item = button:WaitForChild("ItemName")
local rs = game:GetService("ReplicatedStorage")
local VerifyPurchase = rs:WaitForChild("VerifyPurchase")
button.MouseButton1Click:connect(function()
local CanPurchaseTool = VerifyPurchase:InvokeServer(item)
if CanPurchaseTool then
-- Change the GUI to say they bought it
else
button.Text = "Not enough cash"
wait(5)
button.Text = price.Value.."$"
end
end)
Server
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local ShopItems = ServerStorage:WaitForChild("ShopItems")
local VerifyPurchase = Instance.new("RemoteFunction")
VerifyPurchase.Parent = ReplicatedStorage
VerifyPurchase.Name = "VerifyPurchase"
VerifyPurchase.OnServerInvoke(function(Player, ItemToBuy)
print(player.Name.." wants to purchase "..ItemToBuy)
local ItemPrice = ShopItems:FindFirstChild(ItemToBuy) -- ItemToBuy would be a string
if ItemPrice then
local leaderstats = Player:FindFirstChild("leaderstats")
if leaderstats then
if leaderstats.Cash.Value >= ItemPrice then -- Check if they have enough cash
local Tool = ServerStorage:FindFirstChild(ItemToBuy):Clone()
Tool.Parent = Player.Character
return true -- Tell them they can buy it
else
return false -- Tell them they can't buy it
end
end
else
return false
end
end)
I wrote this on mobile so apologies if there’s any mistakes. You can learn more about RemoteFunctions here.