Creating a System that gives someone an item

So I have managed to get a system that gives a player an item and some points when they click a block but I have been unable to make it so that when they refresh or reset they keep the item because currently as soon as you reset it removes the item from your inventory. This is what I have for the code so far and any help would be appreciated.

amount = 10
currencyname = "Points"

local tool = game.ServerStorage["Parkour Trophy"]
local klone = tool:clone()
script.Parent.ClickDetector.MouseClick:connect (function(plr)
if klone.Parent ~= plr.Backpack then
klone.Parent = plr.Backpack
for i,v in pairs(game.Players:GetPlayers()) do
		if v:FindFirstChild("leaderstats") and v then
			v.leaderstats[currencyname].Value = v.leaderstats[currencyname].Value + amount
		end
end
else
end
end)
4 Likes

Well, this would work but it’s NOT efficient.

First, make a boolValue inside the player. Set it’s value to false.
When you give the Tool to the player via the script mentioned above, change the value of the boolValue to true.
Finally, you add a script that runs when the player’s character is added. In the script, you first check if the boolValue’s value is true. If it is, then just give the tool to the player, otherwise, return.

Hope someone posts a better way to do this! :smiley:

2 Likes

How would I create a boolValue inside the player?

You could add this line in a server-sided script

game.Players.PlayerAdded:Connect(function(player)
    local Value = Instance.new("BoolValue")
    Value.Value = false
    Value.Parent = player
end)

That would wait for a player to be added, and once a player would be added, it creates a boolValue. It then sets its value to false and finally, parents it to the player.

2 Likes

Hi!

Your method to give the player the tool looks fine, but the issue with resetting is because the Backpack object of the player instance is independent of what is copied into the pack when a player spawns. This basically means that when the player dies, they lose whatever is in the Backpack.

When your Roblox character respawns or refreshes, the contents of the StarterPack and the StarterGear are copied into the Backpack. So instead of parenting the cloned tool into Backpack, try parenting it to StarterPack instead. This means that the tool will always be copied into the Backpack when your player respawns.

It might be worth reading the following articles to get a better understand of how tools are managed in games:

StarterPack: StarterPack | Documentation - Roblox Creator Hub
StarterGear: StarterGear | Documentation - Roblox Creator Hub
Backpack: Backpack | Documentation - Roblox Creator Hub

Hope this helps,
-Tom :slight_smile:

1 Like

So like this?

amount = 10
currencyname = "Points"

local tool = game.ServerStorage["Parkour Trophy"]
local klone = tool:clone()
script.Parent.ClickDetector.MouseClick:connect (function(plr)
if klone.Parent ~= plr.StarterPack then
klone.Parent = plr.StarterPack
for i,v in pairs(game.Players:GetPlayers()) do
		if v:FindFirstChild("leaderstats") and v then
			v.leaderstats[currencyname].Value = v.leaderstats[currencyname].Value + amount
		end
end
else
end
end)
1 Like

Try it!

Nothing wrong with trial and error, if you don’t see any immediate errors presented in the output consult the documentation, it’s what scripting is all about. From my experience, the StarterPack needs to be accessed via a Local Script. Consider replicating the model by using Replicated Storage and trigger the Local Script through a Remote Event.

If this is a script in the workspace, you need to fire a RemoteEvent and do the cloning and setting the parent there. If you run this from a script in the workspace, the tool will be given to all the players who die and join the game.

So your script should be like this:

Script
amount = 10
currencyname = "Points"

local tool = game.ServerStorage["Parkour Trophy"]
local klone = tool
script.Parent.ClickDetector.MouseClick:connect (function(plr)
if klone.Parent ~= plr.StarterPack then
remoteEvent:FireClient(plr, tool)
for i,v in pairs(game.Players:GetPlayers()) do
		if v:FindFirstChild("leaderstats") and v then
			v.leaderstats[currencyname].Value = v.leaderstats[currencyname].Value + amount
		end
end
else
end
end)

And the LocalScript:

LocalScript
remoteEvent.OnClientEvent:Connect(function(tool)
    local klone = tool:Clone()
    klone.Parent = game:GetService("StarterPack")
end)

Also, your script would not work anyways, because there is NO child called “StarterPack” inside the player.

Edit: Also, the else is unnecessary because you have no code running after that other than ending the if condition itself.

So I put the local script within a remote event or within the players starter scripts?

Putting a LocalScript in a RemoteEvent would never work. I guess I need to explain you what are LocalScripts first. I promise I will make the explanation short and sweet! :grin:

LocalScripts, as the name suggests, work only on the player, which means that the server is not involved in this script whatsoever. So, for a LocalScript to work, it needs to be inside the player itself (doesn’t matter where but the player or the player’s character).

I hope I made it clear that now the LocalScript shouldn’t be in the RemoteEvent, it is supposed to be anywhere inside the player. You can place it anywhere: the StarterGui, the StarterPack, the PlayerScripts, the PlayerCharacter scripts and literally anywhere which is cloning inside the player

Yours,
pranvexploder :smiley:

I see, I put it into player scripts but it doesn’t seem to give the item to the player and also it has a red underline underneath remoteEvent image

Well, that’s because you need to create a RemoteEvent in the ReplicatedStorage and local it in both the scripts.

Add this line to the top of both the scripts:

Line
local remoteEvent = game:GetService("ReplicatedStorage"):WaitForChild("RemoteEvent")

It should work :smiley:

Through local scripts you can’t access ServerStorage, make sure it’s a ServerScript.

Also, don’t forget ipairs is the fastest generator currently, I recommend using index value pairs instead of key , value pair iteration, it will improve performance and speed at which the code is executed.

1 Like

i made already models to do that:
(Buyable tool)
link: https://www.roblox.com/library/4882718716/Buyable-Tools
Give Tool When click part (No Buyable)
link: https://www.roblox.com/library/4882665217/Give-Tool-On-Click-Part
if you want to add tools then just go to the tools folder and add your own tool :wink:
more info about that with the model.
@RomanEmpireThe1st

Actually, you can just move the tool to the ReplicatedStorage. Won’t it work?

you can move the tools also to serverstorage and is still going to work, same as i did with my models that i sent here: Creating a System that gives someone an item - #14 by REALINONOOBYT
@pranvexploder

Oh okay. I got confused reading @XxELECTROFUSIONxX 's post.

Ah ok that is really useful thank you, but I was wondering if there is a way to make it so that they could only click it once?

1 Like

you can do that so is check if the player already have the tool, and if the player already own the tool so is will print that the player already have the tool. :slight_smile:
hope is help you @RomanEmpireThe1st.

Yes that helped I made a check for that but it still removes the item from the player when they reset or refresh.

local folder = game.ServerStorage.Tools
local tool = folder.ParkourTrophy
local Parent = script.Parent.Parent
amount = 10
currencyname = "Points"

script.Parent.ClickDetector.MouseClick:Connect(function(player)
 	local Tool = player.Backpack:FindFirstChild("ParkourTrophy") or player.Character:FindFirstChild("ParkourTrophy")
	if Tool then
		return
	else local plr = game.Players:GetPlayerFromCharacter(player)
	local clone = tool:Clone()
	clone.Parent = player.Backpack
	for i,v in pairs(game.Players:GetPlayers()) do
		if v:FindFirstChild("leaderstats") and v then
			v.leaderstats[currencyname].Value = v.leaderstats[currencyname].Value + amount
		end
		end
		end
end)