Script doesnt work well

at the runservice line its supposed to detect if a player is with a boolvalue and if a different player who is near the player with the boolvalue has a boolvalue or not if the player near the player with the boolvalue doesnt have a boolvalue then he gets a boolvalue inserted into his character. Im not getting any errors and i dont know why it doesnt work please help
code:

local rs = game:GetService("RunService")
--[[
	local value = Instance.new("BoolValue",v.Character)
								value.Name = "Infected"
value = true
--]]
--[[
while wait(2) do 
	local randomdmg = math.random(10,20)
	for i,v in pairs(game.Players:GetPlayers()) do
		if v.Character:FindFirstChild("BoolValue") then
			v.Character:FindFirstChild("Humanoid"):TakeDamage(randomdmg)
			print(randomdmg)
		end
	end
end
--]]
game.ReplicatedStorage.characteradded.OnServerEvent:Connect(function(plr)
	local randomnum = math.random(1,2)
		local last = nil
	             for i,v in pairs(game.Players:GetPlayers()) do
		         if last == nil then
				last = v
			end
		     if randomnum == 2 then
			            local value = Instance.new("BoolValue",last.Character)
					    value.Name = "Infected"
			            value = true
			            local gui = game.ServerStorage.InfectGui:Clone()
			            gui.Parent = last.PlayerGui
			print(plr.Name.." got unlucky and is infected")
		    elseif randomnum == 1 then
			            print(plr.Name.." got lucky and isnt infected")
			
		end
	end
end)

rs.Stepped:Connect(function()
	local last = nil
	for i,v in pairs(game.Players:GetChildren()) do
		if last == nil then
			last = v
		end

		
		if last and v then
			if last.Character and last~= v and v.Character then
				local dist = (last.Character.HumanoidRootPart.Position-v.Character.HumanoidRootPart.Position).magnitude
				if dist <= 5 then
					if last.Character:FindFirstChild("BoolValue") and v.Character:FindFirstChild("BoolValue") == false then
					print("The player "..v.Name.." is close to "..last.Name)
						local value = Instance.new("BoolValue",v.Character)
					    value.Name = "Infected"
					    value = true
					    local gui = game.ServerStorage.InfectGui:Clone()
			            gui.Parent = v.PlayerGui
				end
				last = v
			end
		end
	end
	end
end)

1 Like

Hey dude. Looks like you got a few things going on which might be holding the script back, so I’ll go over what the code is doing and where its not performing the way you want. And I won’t comment on the commented-out part, assuming thats not meant to be running.

  • So in the runService.Stepped signal handler function, you’re iterating through all the players. You check the magnitude between the current iteration’s player.Character variant and the previous iteration’s character. This is a flaw in the algorithm, you’re not checking the magnitude of a character against all other characters, just against one.
  • FindFirstChild() also either returns a roblox class object, or nil. But it will never return false, so this line here is never true, since nil~=false.

if last.Character:FindFirstChild("BoolValue") and v.Character:FindFirstChild("BoolValue") == false then
Try
if last.Character:FindFirstChild("BoolValue") and not v.Character:FindFirstChild("BoolValue") then

How do i make it check against all the other characters? Its still inserting boolvalues into the first player’s character in the server so because it checks for only one that might be the problem. ive been told that it checks for all characters.

Alright well lets start with the first function (characteradded server event handler).
In detail this does the following:

  • Choose a random number between 1 and 2
  • First define a variable ‘last’
  • Loop through every player in the game. On the first iteration last is set to the current player value. You then infect the character of the player defined in ‘last’ if the randomnum is 2.
    • Since last is only ever set when its nil, its only set on the first iteration. This means that if there are 5 players, the code is going to iterate 5 times. Only the first player has the chance to ever get infected (because you only infect ‘last’ which is only set once) and has the chance to get infected 5 times, which means his chances of not getting infected are 1/(2^5).
    • I also noticed you had
      print(plr.Name.." got unlucky and is infected")
      plr is not infected here. The first player in the array returned by Players:GetPlayers() is the one infected. Know that these are different, and this might not infect the player you want it to.

Now onto the second function (runService.Stepped)
It has a similar format, but heres the works.

  • Define a variable ‘last’
  • Iterate through all players. Check the magnitude between the previous player’s character and the current player’s character. If its less than 5 infect player.
    • Now a few things here, this never infects anyone because of this part
      v.Character:FindFirstChild("BoolValue") == false
      my previous response describes why.
  • Second, again you only check 1 player vs 1 player. It does check all players, but it only makes one comparison. Say you have 3 players. Player 1 and 3 are very close, player 2 is far away. Player 1 is infected.
    • You first check if player 1 and player 2 are close, they aren’t so player 2 isn’t infected. Then you check if player 2 and player 3 are close, they aren’t so player 3 isn’t infected.
    • Player 3 should be infected by player 1, but you never make that comparison.

This was a long post. I hope it benefits you to know the logic behind what you’ve wrote better. If you want to check a player against all others, then you’ll have to use nested loops in some way.

Here's how you might program it:
function createTag()
	local tag=Instance.new('BoolValue')
	tag.Name='InfectedTag'
	tag.Value=true
	return tag
end

function randomInfectPlayer(plr)
	local chance = 2
	local rand = math.random(chance)
	if rand % chance==0 then -- Infect
		if plr.Character and not plr.Character:FindFirstChild('InfectedTag') then
			local tag=createTag()
			tag.Parent=plr.Character
		end
	end
end

function checkPlayerContact()
	local players=game:GetService('Players'):GetPlayers()
	for _, player_i in pairs(players) do
		if not (player_i.Character and player_i.Character:FindFirstChild('InfectedTag')) then
			continue	-- Optimize by only comparing infected characters with everyone
		end
		
		for _, player_j in pairs(players) do
			if player_i==player_j or not player_j.Character or player_j.Character:FindFirstChild('InfectedTag') then
				continue
			end
			local diff3 = player_i.Character.HumanoidRootPart.Position - player_j.Character.HumanoidRootPart.Position
			local dist=diff3.Magnitude
			
			if dist<=5 then
				local tag = createTag()
				tag.Parent=player_j.Character
			end
		end
	end
end


game.ReplicatedStorage.characteradded.OnServerEvent:Connect(randomInfectPlayer)
while wait(.25) do
	checkPlayerContact()
end
1 Like