Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

My script makes a backup of something in workspace, but i don't want it to. Why?

Hello, i am trying to make a miner job in my game. Im trying to make a stone thingy. You have to mine stone then wait for it to respawn. When i mine it, it respawns. But it just makes a backup of the stone in workspace for no reason. Here is the script:

hits = 0
script.Parent.ClickDetector.MouseClick:connect(function()
	hits = hits + 1
	if hits == 3 then
		script.Parent = workspace -- just parent the script in a safe area because we need to remove it's parent
		game.Workspace.Mine.Stone:Destroy() -- remove the stone
		wait(3)
		local stone = game.ReplicatedStorage.Stone:Clone() -- clone the stone from replicatedstorage
		stone.Parent = game.Workspace.Mine -- set the parent to the mine
		script:Destroy() -- now safely remove the script because we dont need it
	end
end)

Note: I added the comments to avoid some questions.

8 comments

0

Add a debounce?

0

There's already a debounce. "if hits == 3 then"

0

I'm confused. Does the stone instantly respawns? And do you need to fix that?

0

Okay. The stone respawns after 3 seconds. And when it respawns i think it does in workspace or just clones itself again into workspace.

1

Does this mean you have this script in every stone? You should probably put one script in ServerScriptService to handle all the stone and mineral respawning. It wouldn't be too difficult.

0

Agree with gold. This is done inefficiently. Also, this is not a debounce but you probably wouldn't need one. It makes one due to line 9. Does it make an extra one besides that one?

1

If you want to replace the stone after 3 seconds. It's better to make move it to storage then destroying. It takes less scripts.

0

Confusing.

1 answer

✓ Accepted answer

You are correct in thinking that the script you are using is a bit inefficient. Instead of copying the stone and script over and over again, it could just restore the originals! This script will do just that:

local hits = 0
local target = workspace.Mine.Stone
local targetParent = target.Parent
target.ClickDetector.MouseClick:connect(function(player)
	hits = hits + 1
	if hits < 3 then return end
	--Hide stone
	target.Parent = nil
	--TODO Reward 'player' with inventory or money here
	wait(3)
	--Restore stone and allow mining again
	target.Parent = targetParent
	hits = 0
end)

Notes:

  • The script must be placed in ServerScriptService (I am assuming it is a regular Script, not a LocalScript.)
  • Saying if hits < 3 then return end is the same idea as if hits == 3 then, but avoids an extra indentation.
  • You have to fill in the 'TODO Reward' line with whatever is appropriate
  • This system is open to the abuse of one player trying to mine, getting 2 hits/clicks in, and then another player stealing the 3rd hit and claiming the reward. One method of addressing this (if you are even concerned about it) is to keep track of how many clicks/hits each player has performed separately (and resetting them all when anyone finishes mining the rock). Alternatively, script "who-ever hits it the most will get it so long as at least 3 hits have occurred".
  • If the script errors on line 2 in Online mode (though I don't think it will), change it to workspace:WaitForChild("Mine"):WaitForChild("Stone") - this assumes that both Mine and Stone exist.

Now, if you only have one rock in your entire place, this works fine. However, what if you want multiple rocks? Now, I don't know how you have your Mine folder/model set up. Say that you have lots of Stones in there, but also other stuff that shouldn't be mined. Then we can go through each child and attach the event to any of them that are named "Stone". Each one can have its own local variable hits so that they are kept separate.

local ch = workspace.Mine:GetChildren() --Get all the children in Mine
for i = 1, #ch do --Go through each child
	if ch[i].Name == "Stone" then --If the child is what we're looking for:
		local target = ch[i]
		local hits = 0
		target.ClickDetector.MouseClick:connect(function(player)
			hits = hits + 1
			if hits < 3 then return end
			--Hide stone
			target.Parent = nil
			--TODO Reward 'player' with inventory or money here
			wait(3)
			--Restore stone and allow mining again
			target.Parent = targetParent
			hits = 0
		end)
	end
end

Since we declare hits and target inside the for loop, the function that is connected to the MouseClick event will receive those local variables. Each Stone will have its own function that will have its own target/hits variables.

1 comment

0

The game is singleplayer so you didn't need to add the additional code. But thanks anyways!

This discussion is preserved as it was. New answers, comments, and votes are closed.