2 people joining a level at the same time doesn't work

I’m trying to make a level system where once u reach the end of one level, u can teleport to the next level from a level select menu, however if 2 people try to click the same level at the same time(or around the same time) one of the players doesn’t get teleported while the other does, whoever clicked earlier. This is my code for what happens when the player clicks a level:

	player.CharacterAdded:Connect(function(character)
		local hrp = character:WaitForChild("HumanoidRootPart")  
		playerlevel.OnServerEvent:Connect(function(playero, lev)

			if lev then
				print(playero)
				print(lev)
				checkpointclient = FindCheckpoint(playero.Character, lev) 
			else
				return
			end 
		end) 
		local checkpoint = FindCheckpoint(character, level.Value)  
		RunService.Heartbeat:Wait()

		if checkpointclient ~= nil then 
			print(player.Name)
			print(checkpointclient)
			print("checkpointclient")
			hrp.CFrame = CFrame.new(checkpointclient.Position + Vector3.new(0, 3, 0)) * CFrame.Angles(0, math.rad(checkpointclient.Orientation.Y) + math.rad(0), 0)
			checkpointclient = nil
		else
			print(player.Name)
			print(checkpoint)
			print("checkpoint")
			hrp.CFrame = CFrame.new(checkpoint.Position + Vector3.new(0, 3, 0)) * CFrame.Angles(0, math.rad(checkpoint.Orientation.Y) + math.rad(0), 0)
		end
	end)

Whenever they click on a level, it resets their character(done in the gui script where they click on the level) so the character added function runs and the gui script also fires an event to the server with the player and level that they chose in it. What should happen is

if checkpointclient ~= nil then 
			print(player.Name)
			print(checkpointclient)
			print("checkpointclient")
			hrp.CFrame = CFrame.new(checkpointclient.Position + Vector3.new(0, 3, 0)) * CFrame.Angles(0, math.rad(checkpointclient.Orientation.Y) + math.rad(0), 0)
			checkpointclient = nil
		else

this code should run twice because the variable lev(the level that they chose in the gui) exists which allows this if statement

			if lev then
				print(playero)
				print(lev)
				checkpointclient = FindCheckpoint(playero.Character, lev) 

to run which creates the checkpointclient variable making it not nil, but for some reason it only runs for the first player and then the else statement runs for the 2nd player

I think the issue is because both players share the checkpointclient variable
you could make a table where theTable[thePlayer] = checkpointclient of the player, or adjust your code so you have a checkpoint client in a scope only for one player

1 Like

Thanks for the response. I can’t try the table right now but I think you’re right. Can you elaborate on adjusting my code to have checkpointclient in scope for one player, I’m not sure what u mean. And what if 3 players clicked at the same time would that method still work?

looking at this again, it’s probably easier to just make checkpointclient a local variable or calculate it after doing Heartbeat:Wait()

local checkpointclient
if lev then
   ...
   checkpointclient = ...
else
   return
end
1 Like

Im not sure why but that doesnt work, in fact neither of them get teleported if its a local variable.

check for errors in the output
make sure you defined the variable outside of that if statement

1 Like
player.CharacterAdded:Connect(function(character)
		local hrp = character:WaitForChild("HumanoidRootPart")  
		playerlevel.OnServerEvent:Connect(function(playero, lev) 
			local checkpointclient
			if lev then
				checkpointclient = FindCheckpoint(playero.Character, lev)  
			else
				return
			end 
		end) 
		local checkpoint = FindCheckpoint(character, level.Value)  
		RunService.Heartbeat:Wait()

		if checkpointclient ~= nil then  
			hrp.CFrame = CFrame.new(checkpointclient.Position + Vector3.new(0, 3, 0)) * CFrame.Angles(0, math.rad(checkpointclient.Orientation.Y) + math.rad(0), 0)
			checkpointclient = nil
		else 
			hrp.CFrame = CFrame.new(checkpoint.Position + Vector3.new(0, 3, 0)) * CFrame.Angles(0, math.rad(checkpoint.Orientation.Y) + math.rad(0), 0)
		end

and there are no errors

Edit: I put it outside the character added function and it works, before it kept setting the checkpointclient variable to nil everytime someone died because it was inside the function.

putting it outside the function will still have issues
you may end up with people teleporting to the same checkpoint if they click around the same time

Yea I tested it and if 2 players click different levels at the same time they get teleported to 1. Can u explain a little more in depth on how I could use a table for this?

the basic idea is this

local checkpointclients = {
   [4SHN's player instance] = the checkpoint client for 4SHN,
   [ZeInventor's player instance] = the checkpoint client for ZeInventor,
}

whenever you want to set a checkpointclient for a player, set the value in that table

Thanks, this is the code

	player.CharacterAdded:Connect(function(character)
		local hrp = character:WaitForChild("HumanoidRootPart")  
		playerlevel.OnServerEvent:Connect(function(playero, lev) 	
			if lev then
				checkpointclient[playero.Name] = FindCheckpoint(playero.Character, lev)
			else
				return
			end 
		end) 
		local checkpoint = FindCheckpoint(character, level.Value)  
		RunService.Heartbeat:Wait()

		if checkpointclient[player.Name] ~= nil then  
			print(checkpointclient[player.Name])
			print(player.Name)
			print("checkpointclient")
			hrp.CFrame = CFrame.new(checkpointclient[player.Name].Position + Vector3.new(0, 3, 0)) * CFrame.Angles(0, math.rad(checkpointclient[player.Name].Orientation.Y) + math.rad(0), 0)
			checkpointclient[player.Name] = nil
		else 
			print(player.Name)
			print("checkpoint")
			hrp.CFrame = CFrame.new(checkpoint.Position + Vector3.new(0, 3, 0)) * CFrame.Angles(0, math.rad(checkpoint.Orientation.Y) + math.rad(0), 0)
		end

I created the checkpointclient table outside at the top of the script.