Help with "Pass the Bomb" Minigame bug

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!
    I’m making a “Pass The Bomb” Minigame for my minigame system where a script in workspace hands a random player a bomb, and then the players can pass the bomb around until it explodes and then the script gives a random player a new bomb. Note that this is my first time posting here.

  2. What is the issue? Include screenshots / videos if possible!
    The bomb gets cloned twice when it spawns while being passed back and forth between one player and another that just died.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I tired adding a couple arguments to the part of the workspace script that picks the random player. I’ve also been looking all over dev forum throughout the project.

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

-A BoolValue tracks whether or not the bomb is actively counting down(not exploded), and each player has their own BoolValue that tracks whether or not they have the bomb currently.
-Some parts of the script are managed by other parts of the game, such as the Main script that runs the minigames.

BombScript(inside bomb):

local tool = script.Parent
local RunService = game:GetService("RunService")
local character
local canGive
local play = game.Players:GetPlayerFromCharacter(script.Parent.Parent)
local BombValueLocation = game.Workspace.CurrentMinigame:FindFirstChild("Bomb Blast").BombActive
local PlrBombValueLocation = game.Workspace.CurrentMinigame:FindFirstChild("Bomb Blast").MinigameInfo.PlayerBombValues

tool.Equipped:Connect(function()
	PlrBombValueLocation:WaitForChild("PlrBomb"..play.UserId).Value = true
end)





local function onTouch(otherPart)
	canGive = true
	wait(1)
	local humanoid = otherPart.Parent:FindFirstChild("Humanoid")

	if not humanoid then 
		return 
	end
	if humanoid.Health == 0 then
	--game.workspace.BombActive.Value = false
		return
	end
	--script.Parent.Bomb.Enabled = true
	if humanoid.Parent ~= tool.Parent and canGive and humanoid.Health ~= 0 then
		canGive = false
		tool.Parent = humanoid.Parent
	else
		return
	end
end

tool.Handle.Touched:Connect(onTouch)




local waittime = 1
for count = 10, 0, -1 do
	task.wait(waittime)
	script.Parent.Handle.Timer.time.Text = count
	script.Parent.Handle.Tick:Play()
end

script.Parent.Handle.Boom:Play()
explosion = Instance.new("Explosion")
explosion.BlastRadius = 0
explosion.BlastPressure = 0
explosion.Position = script.Parent.Handle.Position
explosion.Parent = game.Workspace
script.Parent.Parent.Humanoid.Health = 0
PlrBombValueLocation:WaitForChild("PlrBomb"..play.UserId).Value = false
BombValueLocation.Value = false
script.Parent.Handle.Tick:Stop()
script.Parent.Handle.Timer.time.Text = ""
wait(1)


script.Parent:Destroy()

Workspace Script:

Minigame = script.Parent
Functions = require(script.Functions)
local Players = game:GetService("Players")



for i,v in pairs(Minigame.MinigameInfo.TempContestants:GetChildren()) do
		local user = v.Value
		local Obj = Instance.new("BoolValue")
		Obj.Name = "PlrBomb"..user.UserId
		Obj.Value = false
	Obj.Parent = Minigame.MinigameInfo.PlayerBombValues
	
	
	
	user.Character.Humanoid.Died:Connect(function()
		local play = user
		local locate = script.Parent.MinigameInfo.PlayerBombValues
		if locate:FindFirstChild("PlrBomb"..play.UserId)then
			if locate:FindFirstChild("PlrBomb"..play.UserId).Value == true then
				script.Parent.BombActive.Value = false
			end
		end
	end)

	user.CharacterRemoving:Connect(function()
		local play = user
		local locate = script.Parent.MinigameInfo.PlayerBombValues
		if locate:FindFirstChild("PlrBomb"..play.UserId)then
			if locate:FindFirstChild("PlrBomb"..play.UserId).Value == true then
				script.Parent.BombActive.Value = false
			end
		end
	end)
end




if script.Parent.BombActive.Value == false then
	local chosenPlr
	local Plrs = Minigame.MinigameInfo.TempContestants:GetChildren()
	repeat
		chooseAplr = Plrs[math.random(1, #Plrs)]
		chosenPlr = chooseAplr.Value
		wait()
	until chosenPlr.Character and chosenPlr.Parent ~= nil and
 chosenPlr.Character.Humanoid.Health ~= 0 and
 script.Parent.MinigameInfo.PlayerBombValues:FindFirstChild("PlrBomb"..chosenPlr.UserId).Value ~= true
	local bomb = game.ServerStorage.Bomb:Clone()
	bomb.Parent = chosenPlr.Backpack
	local humanoid = chosenPlr.Character.Humanoid
	humanoid:EquipTool(bomb)
	wait(0.5)
	bomb.BombScript.Enabled = true
	script.Parent.BombActive.Value = true

end	

script.Parent.BombActive.Changed:Connect(function()
	wait(3)
	if script.Parent.BombActive.Value == false then
		local chosenPlr
		local Plrs = Minigame.MinigameInfo.TempContestants:GetChildren()
		repeat
			chooseAplr = Plrs[math.random(1, #Plrs)]
			chosenPlr = chooseAplr.Value
			wait()
		until chosenPlr.Character and chosenPlr.Parent ~= nil and chosenPlr.Character.Humanoid.Health ~= 0
		local bomb = game.ServerStorage.Bomb:Clone()
		bomb.Parent = chosenPlr.Backpack
		local humanoid = chosenPlr.Character.Humanoid
		humanoid:EquipTool(bomb)
		wait(0.5)
		bomb.BombScript.Enabled = true
		script.Parent.BombActive.Value = true

	end
end)

--script.Parent:WaitForChild("BombScript").Disabled = false


_G.texto("The Minigame Will End in:")
for i = Minigame.MinigameInfo.Time.Value, 0, -1 do
	_G.timer(i)
	--if #Minigame.MinigameInfo.TempContestants:GetChildren() <= 1 then--regular gameplay
	if #Minigame.MinigameInfo.TempContestants:GetChildren() == -1 then--for testing only
		break
	end
	wait(1)
end


local EndScreen = {}

for i,v in pairs(Minigame.MinigameInfo.TempContestants:GetChildren()) do
	if game.Players:FindFirstChild(v.Name) then
		local player = game.Players:WaitForChild(v.Name)
		if player:FindFirstChild("leaderstats") and player.leaderstats["Coins"] and player.leaderstats:FindFirstChild("Wins") then
			player.leaderstats["Coins"].Value = player.leaderstats["Coins"].Value + 10
			player.leaderstats["Wins"].Value = player.leaderstats["Wins"].Value + 1
			EndScreen[v.Name] = {Won = true}
			local mate = workspace:WaitForChild("Spawns"):GetChildren()[math.random(1, #workspace:WaitForChild("Spawns"):GetChildren())]
			name = v.Value
			local check = player.Character
			if check then
				checkHumanoid = check:FindFirstChild("Humanoid")
				if checkHumanoid then
					check:MoveTo(mate.Position)
				else
				end
			end
		end
	end
end

local TemEndScreen = {}

for i,v in pairs(EndScreen) do
	if v.Won == true then
		TemEndScreen[i] = v
	end 
end

EndScreen = TemEndScreen
game.ReplicatedStorage:WaitForChild("Obj"):FireAllClients("End Screen", EndScreen)
Minigame.MinigameInfo.Finished.Value = true
Functions = require(script.Functions)

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.
hierarchy


Update: Added rest of bomb script, I only added part of it accidentally.

1 Like

maybe you could create a boolvalue/boolean variable that tracks whether or not a bomb is currently in any player’s hand to avoid multiple being created

I would create some sort of modulescript that contains data for whoever currently has the bomb. That way, you don’t have to worry about duplicates.

Ex.

playerWithBomb = player

That’s a good idea, I’m thinking about it right now, also I was thinking I could check if a player already has the bomb before giving them a new one instead of just checking the value but that may or may not fix the issue.

Thanks for the module script idea, I’ll experiment some more and see how I could implement it.

Actually I just tried what I said and checked to see if a player had a bomb first which solved part of the problem but now there is a much bigger problem that I overlooked where the player with the bomb can spam un-equip it which both breaks the script and causes the duplication to come back since the location of the bomb changes when it is unequipped for a split second. I aready have this code block in the bomb script which re-equips the bomb when it is unequipped(by pressing the 1 key on the keyboard)

tool.Equipped:Connect(function()
	character = tool.Parent
	PlrBombValueLocation:WaitForChild("PlrBomb"..play.UserId).Value = true
end)

tool.AncestryChanged:Connect(function(_, parent)
	RunService.Heartbeat:Wait()
	tool.Parent = character
end)

im pretty sure you can prevent items from being dropped by disabling the backpack ui, not 100% sure though

There’s a game on Roblox called Timebomb Duels and in that game you can unequip the bomb for a second just like my script but it will keep working when it is unequipped for a second unlike mine so I gotta figure out a way to control the bomb regardless of whether its in the player or the character. Otherwise I could try to disable the backpack temporarily during the minigame but it would be ideal if I could make the bomb work in either location

I think I figured out the issue for the most part. I added this snippet to the bomb tool script which will always get the player instance whether the bomb tool is in the player backpack or the character:

local play = script:FindFirstAncestorWhichIsA"Player" or game:GetService"Players":GetPlayerFromCharacter(script.Parent.Parent)

And then for the workspace script i added this snippet to the character chooser section so it doesn’t choose a player that already has the bomb currently. It keeps choosing players until one doesn’t have the bomb.

and not chosenPlr.Character:FindFirstChild("Bomb") and not chosenPlr.Backpack:FindFirstChild("Bomb")

So now the bomb tool will work whether it is equipped or not and also it will not be duplicated when passing between a live player and a dead one.

Please let me know if there is anything else I should do to improve my scripts before I call it finished and thank you all for the help so far. I have the ModuleScript idea in mind but i’m not sure how I would implement it or if its even necessary since I got everything working the way i want so far. All the BoolValues will be destroyed when the minigame ends so its not like they will stay there.