Best way to go about coin collection

For my new game, I’m implementing a coin collection system and I’m just wondering whether I do the touch event via the client or the server and how I would go about doing it. Thanks!

1 Like

Obviously you should do it on the server.

Of course you should do it on the server! The client will always be replicated on the server, so doing it on the client will only delay it.

Okay thanks, in doing that should I use one script which detects a touched event for all the coins or should I insert a script in each individual coin?

Better if you have 1 script that can detect all the coins. Make a folder for all the coins and use :GetChildren().

Example

local CoinsFolder = workspace.CoinsFolder

for _,v in pairs(CoinsFolder:GetChildren()) do
    v.Touched:Connect(function(hit)
        local Player = game.Players:GetPlayerFromCharacter(hit.Parent)
        
        if Player then
          --Do something...  
        end
    
    end)
end

I would do something like this:

In ServerScriptService:

game.Players.PlayerAdded:Connect(function(Player)
	local CoinsValue = Instance.new("NumberValue", Player)
	CoinsValue.Name = "Coins"
end)

In each coin:

script.Parent.Touched:Connect(function(Hit)
	if game.Players:FindFirstChild(Hit.Parent.Name) then
		local Plr = game.Players[Hit.Parent.Name]
		Plr.Coins.Value = Plr.Coins.Value + 1
	end
end)

In a store or purchasing system:

local PRICE = 100

script.Parent.MouseButton1Down:Connect(function(Player)
	if Player.Coins.Value >=PRICE then
		local ITEM = game:GetService("ServerStorage"):WaitForChild(ITEM)
		ITEM:Clone().Parent = Player.Backpack
		ITEM:Clone().Parent = Player.StarterGear
		Player.Coins.Value = Player.Coins.Value - PRICE
	else
		print("not enough coins")
	end
end)

Use CollectionService and Tag Editor to make ur job easier. Always do this stuff on the server. DO NOT trust the client in these situations. You can also throw a bit of OOP in there if you want more fucntionalities like play animation after coin is picked up.

Pseudo code

local Coin = { }
Coin.__index = Coin

function Coin.new(obj, pos)
    return setmetatable({
       Object = obj,
       Object.Position = pos,
       Object.Touched:Connect(function(part)
           if part.Parent:FindFirstChild("Humanoid") then
              -- Call an external module script which handles all coin data, and ask it to register so and so coin of so and so player.

              Coin:PlayAnimation()
           end
       end)
    }, Coin)
end

function Coin:PlayAnimation()
    -- Play Animation here

    self:Destroy()
end

function Coin:Destroy()
    self.Object:Destroy()
end

return Coin

Personally I prefer OOP, since that makes my code look more clean, however the choice is yours. If you have any questions, feel free to ask them here.

3 Likes

Server so that you won’t need to make use of RemoteEvents in order to communicate with the server.