Why does this script constantly swap the bool value from player to player instead of cloning it multiple times?

I’m new to scripting and trying to set up a round system. For some reason when the game is started with 1 player the player counter works properly and adds 1 to the table, but when there is multiple players it freaks out and counts more players than there is

how it looks with multiple people

How it looks with one

local list = {}

local counted = game:GetService("ReplicatedStorage").Counted:Clone()

workspace:WaitForChild("ShockwaveBaseplate").Touched:Connect(function(part)
	if part.Parent:FindFirstChild("Humanoid") then
		if part.Parent:FindFirstChild("Counted") then return end
		counted.Parent = part.Parent
		list[#list+1] = game.Players:GetPlayerFromCharacter(part.Parent).UserId
		print(#list)
	end
end)

Hi, so one issue may be due to the fact that you only cloned once! But there is also no debounce used to verify that the code is ran once and only once per character. This would be an issue in this case because multiple parts might touch the BasePlate at the same time and trigger before your return catch actually works.

Try this code and see if it helps.

local list = {}
local deb = false

-- Removed the :Clone() statement from the reference object
local counted = game:GetService("ReplicatedStorage").Counted

workspace:WaitForChild("ShockwaveBaseplate").Touched:Connect(function(part)
	if part.Parent:FindFirstChild("Humanoid") and deb == false then
		if part.Parent:FindFirstChild("Counted") then return end
        deb = true
        -- need to clone EACH time not just once!
        local counted_clone = counted:Clone()
		counted_clone.Parent = part.Parent
		table.insert(list, game.Players:GetPlayerFromCharacter(part.Parent).UserId)
        --list[#list+1] = game.Players:GetPlayerFromCharacter(part.Parent).UserId
		print(#list)
        deb = false
	end
end)

So besides the debounce, which in my opinion is a necessary safeguard, you were only cloning once! So the original :Clone() of counted would be causing a Scope issue. You need to clone each time for each player so they each get their own cloned part!

This part isn’t necessary, but I thought I’d point it out. I changed your line of code where you inserted the UserId into the list by using the build-in table method table.insert so it’ll automatically put your new entry at the end of the list!

table.insert(list, game.Players:GetPlayerFromCharacter(part.Parent).UserId)
1 Like

Thanks this worked!

as a side question how would you go about removing a player’s value from the table if they’re killed?

		if counted_clone.Parent.Health == 0 then
			counted_clone:Destroy()
			list = #list-1
		end

		while #list > 1 do
			wait(0.5)
			print(#list)
		end
		if #list <= 1 then 
			print("The winner is...", #list)
		end
		deb = false
	end
end)

I tried this but it doesn’t really work for me

Hey! Glad that it worked for you. :slight_smile:

Pretty simple actually. First, Health is a property of Humanoid and does determine if the Player is dead or alive, but using it as stated does not work because it is not “loop checked” or as we call listened for. To do this, just use a connection on the Humanoid checking if they Died!

Also, I believe this snippet from above is encapsulated within the code stated in the first post, and if so you can get the Humanoid the way described below.

You also want to make sure remove the correct player from the list as well. The safest way to do so, is just to find them in the table via their UserId (the same way we inserted them)!

part.Parent.Humanoid.Died:Connect(function()
	counted_clone:Destroy()
    local UserID = game.Players:GetPlayerFromCharacter(part.Parent).UserId
    local playerIndex = table.find(list, UserID)
	table.remove(list, playerIndex)
end)

Here is an excellent documentation page on tables. Give it a read! It will help with understanding how to manipulate tables exactly how you want to do so.

1 Like

Thanks this helped, but now when I have more than 2 players in the game at once it doesn’t detect more than two

image

1 Like

Can you provide the full code so I can see how it looks in its entirety now?

Not entirely sure what it is without seeing code, but it could have to do with the debounce, but will have to see!

ofc

local list = {
	
}
local deb = false

-- Removed the :Clone() statement from the reference object
local counted = game:GetService("ReplicatedStorage").Counted 

workspace:WaitForChild("ShockwaveBaseplate").Touched:Connect(function(part)
	if part.Parent:FindFirstChild("Humanoid") and deb == false then
		if part.Parent:FindFirstChild("Counted") then return end
		deb = true
		-- need to clone EACH time not just once!
		local counted_clone = counted:Clone()
		counted_clone.Parent = part.Parent
		table.insert(list, game.Players:GetPlayerFromCharacter(part.Parent).UserId)
		--list[#list+1] = game.Players:GetPlayerFromCharacter(part.Parent).UserId
		part.Parent.Humanoid.Died:Connect(function()
			counted_clone:Destroy()
			local UserID = game.Players:GetPlayerFromCharacter(part.Parent).UserId
			local playerIndex = table.find(list, UserID)
			table.remove(list, playerIndex)
		end)
		
		while #list > 1 do
			wait(0.5)
			print(#list)
		end
		if #list <= 1 then 
			print("The winner is...", #list)
		end
		deb = false
	end
end)

It’s this

while #list > 1 do
	wait(0.5)
	print(#list)
end

It’s looping so it never gets to the

deb = false

The easiest solution for this could be to just put it outside of the .Touched event. like:

local list = {
	
}
local deb = false

-- Removed the :Clone() statement from the reference object
local counted = game:GetService("ReplicatedStorage").Counted 

workspace:WaitForChild("ShockwaveBaseplate").Touched:Connect(function(part)
	if part.Parent:FindFirstChild("Humanoid") and deb == false then
		if part.Parent:FindFirstChild("Counted") then return end
		deb = true
		-- need to clone EACH time not just once!
		local counted_clone = counted:Clone()
		counted_clone.Parent = part.Parent
		table.insert(list, game.Players:GetPlayerFromCharacter(part.Parent).UserId)
		--list[#list+1] = game.Players:GetPlayerFromCharacter(part.Parent).UserId
		part.Parent.Humanoid.Died:Connect(function()
			counted_clone:Destroy()
			local UserID = game.Players:GetPlayerFromCharacter(part.Parent).UserId
			local playerIndex = table.find(list, UserID)
			table.remove(list, playerIndex)
		end)

		if #list <= 1 then 
			print("The winner is...", #list)
		end
		deb = false
	end
end)

while #list > 1 do
	wait(0.5)
	print(#list)
end
1 Like

When I do that it just stops looping after 1, like this

image

Okay, just change this code

to something like

while true do
	wait(0.5)
    if #list > 1 then
	    print(#list)
    end
end