Running a function inside itself

i have a game, where whenever player A touches player B, B gets infected, and whoever touches B becomes infected too, and while i was doing so i ran into a problem that i never expected i would run into.

when player A becomes infected, a touched event is connected to him, and when he touches B, the same thing happens, but the problem is, the code would look like this

A.Touched:Connect(function(hit)
 hit.Touched:Connect(function(hit)
  hit.Touched:Connect(function(hit)
   hit.Touched:Connect(function(hit)
   --and so on
   end)
  end)
 end)
end)

to avoid that problem, i tried this

local function infection(hit)
 hit.Touched:Connect(infection(hit))
end
A.Touched:Connect(infection(hit))

but it didn’t seem to work.
any ideas ?
i wanna make the code sort of work like a mirror facing another mirror

2 Likes

It’s very hard to tell what you are trying to do, but consider disconnecting events when you don’t want them running.

Honestly I just wouldn’t recommend running events inside of other events, it doesn’t really work. You can use some sort of variable to store whether or not a certain parts been hit, but not just do event → event → event with the same hit variable.

1 Like

I think this is closer to what you want.

local function infection(hit)
 hit.Touched:Connect(infection)
end
A.Touched:Connect(infection)

You might want to reconsider and make it a table-based system later on so you can keep track of everyone.

2 Likes

oh, i just realized, the code i wrote (same as yours) works normally, i just misspelled infection
the problem is solved, but can you tell me about the table-based system ? i already store the infected players in a table, but i don’t really know how to achieve this with that.

In the interest of giving a good answer, I’m first going to answer your direct question, and then state why I think it’s a bad idea, and the solution I would use instead.

The following code will work to achieve your desired result:

function infectionTouch(hit)
  hit.Touched:Connect(infectionTouch)
end

A.Touched:Connect(infectionTouch)

So, if this works, what’s the issue with this solution?

Well, you’re going to have one heck of a lot of connections for a start. This method doesn’t check to see if the touching object is already connected, as well as not checking if you’re hitting a player (I presume this is what you want?). There’s also the issue that you can’t get the number of players or the infected players themselves.

I would recommend rewriting this to use CollectionService, in a similar way to the following (Untested code ;D):

local CollectionService = game:GetService("CollectionService")

CollectionService:GetInstanceAddedSignal("InfectedPlayer"):Connect(function(instance) 
  -- At this point, `instance` is the HumanoidRootPart of the player that got infected. This function will only be fired once per player.
  
  instance.Touched:Connect(function(hit)
    if hit.Parent:FindFirstChild("Humanoid") and not CollectionService:HasTag(hit.Parent.Humanoid.HumanoidRootPart, "InfectedPlayer") then
      CollectionService:AddTag(hit.Parent.Humanoid.HumanoidRootPart, "InfectedPlayer")
    end
  end)
end)

Simply tag the player you wish to be “patient zero” with InfectedPlayer and it should work.

2 Likes

you don’t have to worry about most of what you said, the code i sent is just a basic code of my actual code, which in the code, i do check if the hit is a player and if he’s not already infected, and at some point in the game all the players will get destroyed so the events should be automatically disconnected.
and about CollectionService, after i learn to use it properly i will most likely switch to it.