Script breaks when the player resets character

So I have this local script under startergui that is supposed to work like this: There are 7 cubes around the game that you need to click for an egg’s badgegiver to work, and there is a sign that has a counter GUI of how many cubes you got, so basically just to keep track.

Now the script works perfectly fine except for when the player resets and keeps hunting for the rest of the cubes, they stop working (they don’t change color, and nothing happens to the cubes) & it doesn’t give me anything in output. How do I fix it so that nothing resets and the script keeps working even if the player resets?

Current localscript inside startergui: (a bit messy sorry, but I like it this way so that I can understand it easier)

local Part1 = game:GetService('Workspace'):WaitForChild("Cube1")
local Part2 = game:GetService('Workspace'):WaitForChild("Cube2")
local Part3 = game:GetService('Workspace'):WaitForChild("Cube3")
local Part4 = game:GetService('Workspace'):WaitForChild("Cube4")
local Part5 = game:GetService('Workspace'):WaitForChild("Cube5")
local Part6 = game:GetService('Workspace'):WaitForChild("Cube6")
local Part7 = game:GetService('Workspace'):WaitForChild("Cube7") --== Change this to what you want, and to the parts name
--== Then add all the other parts

local counter = game.Workspace.Throne.Sign.Counter.SurfaceGui.TextLabel

local checks = 0 --== This will be counting how many have been pressed
local function checkCount() --== Function for checking the counts (this is optional, if you want something else let me know)

	if checks == 7 then

		game.Workspace.Throne["Sorcus Egg"].BadgeGiver.Enabled = true

	end	
end

Part1.ClickDetector.MouseClick:Connect(function() --== Add this for each button

	Part1.ClickDetector:Destroy() --== So it can't be pressed again	
	Part1.Color = Color3.fromRGB(189, 0, 0)
	Part1.Glow.Enabled = false
	Part1.ParticleEmitter.Enabled = false
		for _, child in Part1:GetChildren() do
			if child:IsA("Decal") then
				child.Transparency = 1
			end
		end

	checks += 1 --== Counts that the player pressed a button
	checkCount() --== Run this after each button is pressed or run it in a loop
	counter.Text = checks

end)

Part2.ClickDetector.MouseClick:Connect(function() --== Add this for each button

	Part2.ClickDetector:Destroy() --== So it can't be pressed again	
	Part2.Color = Color3.fromRGB(189, 0, 0)
	Part2.Glow.Enabled = false
	Part2.ParticleEmitter.Enabled = false
	for _, child in Part2:GetChildren() do
		if child:IsA("Decal") then
			child.Transparency = 1
		end
	end

	checks += 1 --== Counts that the player pressed a button
	checkCount() --== Run this after each button is pressed or run it in a loop
	counter.Text = checks

end)

Part3.ClickDetector.MouseClick:Connect(function() --== Add this for each button

	Part3.ClickDetector:Destroy() --== So it can't be pressed again	
	Part3.Color = Color3.fromRGB(189, 0, 0)
	Part3.Glow.Enabled = false
	Part3.ParticleEmitter.Enabled = false
	for _, child in Part3:GetChildren() do
		if child:IsA("Decal") then
			child.Transparency = 1
		end
	end
	
	checks += 1 --== Counts that the player pressed a button
	checkCount() --== Run this after each button is pressed or run it in a loop
	counter.Text = checks

end)

Part4.ClickDetector.MouseClick:Connect(function() --== Add this for each button

	Part4.ClickDetector:Destroy() --== So it can't be pressed again	
	Part4.Color = Color3.fromRGB(189, 0, 0)
	Part4.Glow.Enabled = false
	Part4.ParticleEmitter.Enabled = false
	for _, child in Part4:GetChildren() do
		if child:IsA("Decal") then
			child.Transparency = 1
		end
	end
	
	checks += 1 --== Counts that the player pressed a button
	checkCount() --== Run this after each button is pressed or run it in a loop
	counter.Text = checks

end)

Part5.ClickDetector.MouseClick:Connect(function() --== Add this for each button

	Part5.ClickDetector:Destroy() --== So it can't be pressed again	
	Part5.Color = Color3.fromRGB(189, 0, 0)
	Part5.Glow.Enabled = false
	Part5.ParticleEmitter.Enabled = false
	for _, child in Part5:GetChildren() do
		if child:IsA("Decal") then
			child.Transparency = 1
		end
	end
	
	checks += 1 --== Counts that the player pressed a button
	checkCount() --== Run this after each button is pressed or run it in a loop
	counter.Text = checks

end)

Part6.ClickDetector.MouseClick:Connect(function() --== Add this for each button

	Part6.ClickDetector:Destroy() --== So it can't be pressed again	
	Part6.Color = Color3.fromRGB(189, 0, 0)
	Part6.Glow.Enabled = false
	Part6.ParticleEmitter.Enabled = false
	for _, child in Part6:GetChildren() do
		if child:IsA("Decal") then
			child.Transparency = 1
		end
	end
	
	checks += 1 --== Counts that the player pressed a button
	checkCount() --== Run this after each button is pressed or run it in a loop
	counter.Text = checks

end)

Part7.ClickDetector.MouseClick:Connect(function() --== Add this for each button

	Part7.ClickDetector:Destroy() --== So it can't be pressed again	
	Part7.Color = Color3.fromRGB(189, 0, 0)
	Part7.Glow.Enabled = false
	Part7.ParticleEmitter.Enabled = false
	for _, child in Part7:GetChildren() do
		if child:IsA("Decal") then
			child.Transparency = 1
		end
	end
	
	checks += 1 --== Counts that the player pressed a button
	checkCount() --== Run this after each button is pressed or run it in a loop
	counter.Text = checks

end)

1 Like

Either put your script under StarterPlayerScripts or have the script under a ScreenGUI that won’t reset on spawn.
image

D.R.Y (Don’t repeat yourself). Instead of having Part1.Click... Part2.Click... Part3.Click...
You should put all the parts you want to connect to the same function in a table. Something like this:

local PartTable = {Part1, Part2, Part3..} --Put your parts here

for _,Part in PartTable do
 Part.ClickDetector.MouseClick:Connect(function ()
  --Your code here
end)
end
2 Likes

That’s why the script breaks, when a script is under StarterGui and it’s not under a UI with ResetOnSpawn set to false it will reset every time the player spawns. So I assume what is happening is that every time the player respawns/resets, the script reloads setting check back to 0. To fix the issue you have to parent the local script under StarterPlayerScripts so it only loads once when the player joins the game. Also, I assume your script will never award any badge because everything it does is client-sided meaning that when BadgeGiver.Enabled runs it won’t replicate to the server, and only the server can reward badges for security reasons.

For the sake of helping, I decided to clean up your code as much as I could:

local Part1 = workspace:WaitForChild("Cube1")
local Part2 = workspace:WaitForChild("Cube2")
local Part3 = workspace:WaitForChild("Cube3")
local Part4 = workspace:WaitForChild("Cube4")
local Part5 = workspace:WaitForChild("Cube5")
local Part6 = workspace:WaitForChild("Cube6")
local Part7 = workspace:WaitForChild("Cube7") 

local parts: {BasePart} = {Part1, Part2, Part3, Part4, Part5, Part6, Part7} 
local counter = workspace.Throne.Sign.Counter.SurfaceGui.TextLabel

local checks = {} --which parts have been clicked?
for _, part in pairs(parts) do
	local detector = part:FindFirstChildWhichIsA("ClickDetector")
	detector.MouseClick:Connect(function()
		detector:Destroy()
		--just in case so it can't be bypassed with auto clickers
		if not table.find(checks, part) then table.insert(checks, part) end
		part.Color = Color3.fromRGB(189, 0, 0)
		part.Glow.Enabled = false 
		part.ParticleEmitter.Enabled = false 
		for _, child in pairs(part:GetChildren()) do
			if child:IsA("Decal") then child.Transparency = 1 end 
		end
		counter.Text = #checks 
		if #checks < #parts then return end 
		--Here the following issue arise:
		--Enabling the BadgeGiver on the client wont activate on the server meaning it wont give the badge
		--If you use a remote to enable it server side all the players will be able to claim the badge
		--So to make this actually work you will have to create client -> server communication with remotes
		--Basically the BadgeGiver should fire a badge remote to the server when the player touches it
		--The server then applies custom checks to check if the player cheated or no
		--if the request seems valid(and not manually fired with exploits) reward the badge on the server
		--For this you will have to read some docs about how remotes work
		local sorcus = workspace.Throne:FindFirstChild("Sorcus Egg")
		sorcus.BadgeGiver.Enabled = true
	end)
end

This code will still not work, however, for the issue mentioned with comments in it. To fix the issue you will have to dive a bit into how RemoteEvents and the client-server model works.

4 Likes

I tried putting the script under StarterPlayerScripts but it seems like the issue still presists