How do i make a reward system?

So, i want to make a reward system of pets which costs in-game currency, and the reward system will give them the pet for free, and im using the shop system:

local Rep = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")

local event = Rep:FindFirstChild("PetAdd")
local Data = require(Rep.ShopData)

local petsdaata = Data["Pets"]
local errors = Data["ErrorMessages"]

event.OnServerEvent:Connect(function(player, object, bought)
		print(object)
		print("1")
		local objectdata = petsdaata[object]
		local prices = objectdata["Cost"]
		print("2")
		local Shop = player.PlayerGui:FindFirstChild("Menu")
		local PetsFrame = Shop.PetsFrame.PetsFrame
		print("3")
		--local Btton = frame
		--print(Btton)
--		local HasBought = Btton:FindFirstChild("HasBought")
		print("Phase1")
		--if HasBought ~= nil then
			print("Phase1.5")
			if not bought then
				print("Phase2")
				if not prices or not objectdata then
					player:Kick(errors["Error004"])
				end
			    if player.NOOOOOOB.Cash.Value >= prices then
				print(prices)
				print(prices)
				print("Phase3")
				--	HasBought.Value = true
					player.NOOOOOOB.Cash. Value = player.NOOOOOOB.Cash.Value - prices
					--Substract cash
					local Pet = player:FindFirstChild("Pet") --Finds value of the player
					if Pet then
						print("Phase4")
						Pet.Value = object
						local Char = game.Workspace:FindFirstChild(player.Name)
						if Char then
							
							for  _,  clearChild in ipairs(Char:GetChildren()) do 
								if clearChild.Name == "Pet" then
									clearChild:Destroy()
								end --we should print("e")
							end
							local UpperTorso = Char:FindFirstChild("UpperTorso")
							if UpperTorso then
								for i,clearweld in pairs(UpperTorso:GetChildren()) do
									if clearweld.Name == "PetWeld" then
										clearweld:Destroy()
									end	
								end
								local PetPart = game.Lighting.Pets:FindFirstChild(object)
								if PetPart then
									local PetWeld = Instance.new("Weld",UpperTorso)
									PetWeld.Name = "PetWeld"
									PetWeld.C0 = CFrame.new(3,1,0)
									PetWeld.Part0 = UpperTorso
									local NewPet = PetPart:Clone()
									NewPet.Parent = Char
									NewPet.Name = "Pet"
									print("bigrobuxBIGimeanBUGGGGGGGGGGGGGGGGGGGGGG")
									
									PetWeld.Part1 = NewPet
					
									NewPet.Anchored = false
									NewPet.CanCollide = false
									local OwnedPets = player:FindFirstChild("OwnedPets")
									if OwnedPets then
										local Findif = OwnedPets:FindFirstChild(object)
										if Findif then
										else
											local newitem = Instance.new("Folder",OwnedPets)
			                				newitem.Name = object
										end
									end
								end
							end
						end
					end
				end
			end
	print("yek")
		end
		
		--	end	
	--	end
end)

The problem, is that i dont know how i can achieve that, i tried to add a value to the event, which was “reward”, and if that value was true, then the pet will be free, but that’s client sided, and hackers can easily abuse that.

The main question: How can i do this?

Thanks for responding :+1:

1 Like

Hi there! I’d love to help you work on your shop system, but your question seems a bit too general to answer. Could you condense your question a bit?

If your question is about how to handle a safe serversided connection with a shop system, your answer would be to utilize multiple scripts and RemoteEvents (RemoteEvent | Documentation - Roblox Creator Hub). If you are making a GUI based shop system, you could have a localscript that uses a remote event to fire purchase requests to the server for example. The server would then assess if enough points are in the player’s stats and if so grant the player the reward.

1 Like

Ok, i will explain better:

So, i want to make a reward system of stuff in the shop, the reward system will give you a specific item from the shop which is not free, you must buy it with ingame currency, but i don’t know how i can achieve that.

The script i have sent in the first post is outdated, if you require the new, here it is:

local Rep = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")

local event = Rep:FindFirstChild("PetAdd")
local Data = require(Rep.ShopData)

local petsdaata = Data["Pets"]
local errors = Data["ErrorMessages"]

event.OnServerEvent:Connect(function(player, object, bought)
	local objectdata = petsdaata[object]
	local prices = objectdata["Cost"]
	
	local currency = objectdata["Currency"]
	
	if not bought then
		if not objectdata then
			player:Kick(errors["Error004"])
		end
		
		if not objectdata["Offsale"] then
			if player.NOOOOOOB.Cash.Value >= prices then			
				player.NOOOOOOB:FindFirstChild(currency).Value = player.NOOOOOOB:FindFirstChild(currency).Value - prices
					
				local Pet = player:FindFirstChild("Pet")
				if Pet then
					Pet.Value = object
					local Char = game.Workspace:FindFirstChild(player.Name)
					if Char then
							
						for  _,  clearChild in ipairs(Char:GetChildren()) do 
							if clearChild.Name == "Pet" then
								clearChild:Destroy()
							end --we should print("e")
						end
						local UpperTorso = Char:FindFirstChild("UpperTorso")
						if UpperTorso then
							for i,clearweld in pairs(UpperTorso:GetChildren()) do
								if clearweld.Name == "PetWeld" then
									clearweld:Destroy()
								end	
							end
							local PetPart = game.Lighting.Pets:FindFirstChild(object)
							if PetPart then
								local PetWeld = Instance.new("Weld",UpperTorso)
								PetWeld.Name = "PetWeld"
								PetWeld.C0 = CFrame.new(3,1,0)
								PetWeld.Part0 = UpperTorso
								local NewPet = PetPart:Clone()
								NewPet.Parent = Char
								NewPet.Name = "Pet"
								print("bigrobuxBIGimeanBUGGGGGGGGGGGGGGGGGGGGGG")
									
								PetWeld.Part1 = NewPet
				
								NewPet.Anchored = false
								NewPet.CanCollide = false
								local OwnedPets = player:FindFirstChild("OwnedPets")
								if OwnedPets then
									local Findif = OwnedPets:FindFirstChild(object)
									if Findif then
									else
										local newitem = Instance.new("Folder",OwnedPets)
			               				newitem.Name = object
									end
								end
							end
						end
					end	
				end
			end
		else
			player:Kick(errors["Error006"])
		end
	end
end)

The script makes sanity checks, it checks if the item is offsale, or if there’s an item with the name, and substract the cash, about substracting cash, this is my problem, since when the game wants to give an item as reward, i don’t know how to check if the item is getting sent as reward, and don’t substract the cash since it’s a reward, how i do that? Any attempts that i did failed.

If I’m understanding correctly, you are having issues trying to give a player a reward from outside the shop script that you essentially want to be free because they earned it. If so, have you considered saving tables of data to a player’s datastores? That way you can just have any script interface with the datastore directly and modify data. If you are uncomfortable with modifying tables from within a script you can use this handy module I was given to convert the table to a studio folder, that may make it easier for you. https://www.roblox.com/library/590549414/OAuth2-Table-Module

Overall the system you are requesting is unfortunately going to be a bit more robust than what you currently have set up, but I’m sure you can make it work pretty easily with that module. If there’s anything else I can do let me know!

I didn’t understand correctly, and i think this is not the answer that i was asking…

Here is an example about what i tried to do (Reward System) (Poor example)

onClicking(player) --I know this doesn't works, just an example that player clicks
game.ReplicatedStorage.Event:FireEvent(player, object, reward)
end

and here is the server

game.ReplicatedStorage.Event.OnServerEvent(function(player, object, reward)
      if reward then --If this is a reward
          local PetClone = Pet:Clone()
          PetClone.Parent = player.character
      else --If this was not a reward
          player.Coins = player.Coins - petvalue
          local PetClone = Pet:Clone()
          PetClone.Parent = player.character
end)

But this was client-sided, and a hacker can easily get everything from the shop by using this.

[Edit: fixed reply @monochromattic]

Yes, that sounds very vulnerable to attack. Let me find a snippet of my code to show you.

event.OnServerEvent:Connect(function(player, skin, purchaseName)
    local playerData = ServerStorage.System:WaitForChild(player.Name):WaitForChild("PlayerData")

    local price = SkinStorage[purchaseName].Price.Value --price of requested skin on server
    if playerData.Shards.Value >= price and [player owns skin on our datastore] then 
        playerData.Shards.Value = playerData.Shards.Value - price --subtract cost from datastore
        [add skin on datastore]
    end
end)

This is an abridged code reference but I hope it helps you think about how to secure your shop from exploits a bit.

Yeah, i know that, the script i sent recently was my reward system which is more vulnerable. Before of that, i have written the main shop script, which is more secured. The reward system gives a specific item in the store for free.