Is running .Touched event on 1000+ parts bad?

On games like obbies or tycoons there is a lot of interactive parts like checkpoints, killbricks, etc. I used to script them using the Humanoid.Touched event and then checking if the name of the part is for example “KillBrick”.
But since this runs for everything that every player touches, it has a really long delay before the event gets detected. (even up to 3 seconds on low-end devices :grimacing:)

So I’m wondering if it would be better to put all those KillBricks in 1 table and run the .Touched even on them in a for in pairs() loop. From what I see on the forum, this seems to be the best way. But is it still effective if there’s a few thousand parts who all are waiting for a .Touched event and also have a wait() debounce? (or maybe there’s even another way I haven’t thought of)
Thanks in advance :slight_smile:

Do you have an example script, because I don’t under stand why would you want to add wait :smiley:

Depending on how many players there are you could have a HeartBleed/Stepped event which runs every frame checking :GetTouchingParts() and if any parts appear which should cause the player to die you can act accordingly. Providing your killing parts are named differently to other parts this shouldn’t be too difficult to implement.

I still think a single script which connects a Touched event to each kill part is more efficient though.

Actually, what you could do is instead of connecting Touched events to all of the kill parts you can instead connect them to the limited number of parts a player’s character model has then when one of those events is fired check the part which caused the event to fire and if it’s a kill part then kill the player’s character.

1 Like

Here’s an example code if you want. Debounce Patterns | Roblox Creator Documentation
But the wait is just for the debounce.

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()

for _, part in ipairs(character:GetDescendants()) do
	if part:IsA("BasePart") then
		part.Touched:Connect(function(hit)
			if hit.Name == "Kill" then --change to name of kill part
				character:BreakJoints()
			end
		end)
	end
end

Local script in StarterCharacterScripts as an example of what I was discussing previously.

1 Like

In my opinion there’s no reason for adding the wait, maybe the thing that is causing the delay is the wait, not the detection. For what I would do is:

local player = game.players.localplayer
local char = player.character
local part = char:GetDescendents()

if part:IsA("BasePart") then
   part.Touched:Connect(function(obj)
      if obj.name == "KillPart" then
          -- whatever you wanna do here
      end
   end)
end

so, as you can see, there is no reason you should add a wait! :smiley:

The server size is 40 so that first option is probably not best in this case.

Will that not lag or be delayed even with 1000+ killparts?

Ohh yeah that could work. But what if 2 or more body-parts touch the same killbrick at once?

GetDescendents() should be GetDescendants() and remember that it returns an array which you need to loop over.

It might attempt to kill the player twice in the same frame but that’s about it (they will only die once).

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

for _, part in ipairs(character:GetDescendants()) do
	if part:IsA("BasePart") then
		part.Touched:Connect(function(hit)
			if hit.Name == "Kill" then --change to name of kill part
				if humanoid:GetState() == Enum.HumanoidStateType.Dead then
					return
				end
				humanoid:TakeDamage(humanoid.Health)
			end
		end)
	end
end

This isn’t necessary but the change would check if the player is already dead and stop the function immediately if they are.

In the case of killparts that’s true. But for example when they reach a checkpoint, they receive some coins. And this only should happen once, so that would be a problem.
I guess some kind of global debounce on the player would work. But then maybe it’s better and simpler to just put the .Touched event for each individual part.

Just award the coins on leaderstat change to avoid awarding them multiple times.

1 Like

Oh maybe I didn’t explain that well. But right now there is no debounce in my script, so that’s not what is creating the delay.
But if I would use the .Touched event on each individual killbrick then a debounce is really useful. And it’s actually used by a lot of developers.

Oh yeah that’s possible.
I will just try out both ways (either on all killbricks, or on the player character). And then see which one is best. Thank you and @Mustroomf !