How would I prevent duplicate scripts that follow the same purpose?

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

A simple method to spawn coins in a set position that do its thing of ususlly adding to the currency each time.

  1. What is the issue? Include screenshots / videos if possible!

A lot of duplicate
scripts (current game issue)

Unsure what is the most optimal method/ if there are different coin types.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I checked if anyone else had a similar issue and I wasn’t able to find one or I just missed it.

I did try doing a for loop where i copy the script in each part but I think that may repeat the same issue.

Do not place scripts on each coin. You should perform the task with a Module. Each coin on touch/grab/ect, should be connected to the Module, asking for only one function to give the currency to the player.

Like, you run one function of the Coins_Module. That module search for coins placement, clone a coin from ServerStorage, place that model in workspace, connect a touch event to that coin, that calls another function in Module “CoinTaken” that function will perform the money giving based on the type of coin.

One function will be used for all coins in workspace, and all coins were created by another one function

That is a very good method! I’ll be sure to try it!

1 Like

Im not sure if this is how it would be done…

local coins = {}

local Tokens = workspace:FindFirstChild("Tokens")

local ServerStorage = game:GetService("ServerStorage")
local CoinFolder = ServerStorage:FindFirstChild("Coins")

function coins.New(position, Type)
	local desiredCoin = CoinFolder:FindFirstChild(Type)
	local NewCoin = desiredCoin:Clone()
	
	NewCoin.Parent = Tokens
	NewCoin.Position = position
end

return coins

im unsure on the coin taking and respawning, its what puzzled me.

1 Like

Sure, that works. I suppose you will be calling that module to create the coins many times, sending positions for the coins and the types.

Just for testing, Im would be calling that module with this script to create one coin at position 0,5,0. And sending a type “Gold”

local coins = require(script.Parent:WaitForChild("coins"))
wait(5)
warn("do coin")
coins.New(Vector3.new(0,5,0), "Gold")

Then the module would create that coin and after that connect an event, for my testing I included a ClickDectector in the Gold coin model part

local coins = {}

local Tokens = workspace:FindFirstChild("Tokens")

local ServerStorage = game:GetService("ServerStorage")
local CoinFolder = ServerStorage:FindFirstChild("Coins")

-- When a coin is clicked do stuff
coins.CoinTaken = function(player, CoinType, TheCoin)
	warn(player, CoinType)
	local PreviousPos = TheCoin.Position
	TheCoin:Destroy()
	
	-- WAIT 5 seconds to spawn that coin again
	task.delay(5, function()
		coins.New(PreviousPos, CoinType)
	end)
end

coins.New = function(position, Type)
	local desiredCoin = CoinFolder:FindFirstChild(Type)
	local NewCoin = desiredCoin:Clone()

	NewCoin.Parent = Tokens
	NewCoin.Position = position
	
	NewCoin:WaitForChild("ClickDetector").MouseClick:Connect(function(player)
		coins.CoinTaken(player, Type, NewCoin)
	end)
end

return coins

It prints on a warn the player and the coin they collected and destroy it after the click

EDIT: Respawn with delay of 5 seconds

I uh got a error which im unsure on…

local coins = {}

local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")

local Tokens = workspace:FindFirstChild("Tokens")
local CoinFolder = ServerStorage:FindFirstChild("Coins")

-- When a coin is clicked do stuff
coins.CoinTaken = function(player, CoinType, TheCoin, state)
	
	if not state then
		state = true
		
		warn(player, CoinType)

		local PlayerToFind = Players:GetPlayerFromCharacter(player.Parent)
		local LS = PlayerToFind:FindFirstChild("leaderstats")
		LS.Tokens.Value += 1
		CoinType.Collect:Play()

		CoinType:Destroy()


		local PreviousPos = TheCoin.Position
		TheCoin:Destroy()

		-- WAIT 5 seconds to spawn that coin again
		task.delay(5, function()
			coins.New(PreviousPos, CoinType)
			state = true
		end)
	end
end

coins.New = function(position, Type)
	local desiredCoin = CoinFolder:FindFirstChild(Type)
	local NewCoin = desiredCoin:Clone()

	NewCoin.Parent = Tokens
	NewCoin.Position = position

	NewCoin.Touched:Connect(function(player)
		coins.CoinTaken(player, Type, NewCoin, false)
	end)
end

return coins
ReplicatedStorage.CoinHandler:20: attempt to index nil with 'Play'  -  Server - CoinHandler:20

EDIT: I GOT IT TO WORK! IM JUST UNSURE WHY THE SOUND DOESN’T PLAY!

Putting them in a folder is a good plan.

I’d also recommend looking into CollectionService instead of a folder: I don't get why I should use Collection Service - #4 by nicemike40

The sound doesn’t play because sound effects are client-sided, not server-sided. You should either play the sound effect on the client with a LocalScript when the user clicks the coin, or send a remote event to the user that plays the sound effect when triggered.

I figured that PlayOnRemove could work, it should be all working but I was thinking on how to make a little bounce effect once collected

1 Like

nevermind:

ReplicatedStorage.CoinHandler:17: attempt to index nil with 'WaitForChild'  -  Server - CoinHandler:17