Keeping players from teleporting themselves in game

there are objects players can pick up for points in game. either i will have a heartbeat to keep track of the player’s distance from the objects to see whether they can pick it up or i will have a touched event then check their distance to see if they can pick it up… but for anti teleporting would it make sense to just do everything in a heartbeat?

What do you mean by touched event on the client?

will do touched events on server. not client. corrected. but let me know if you have any comments regarding the anti teleport

Have you checked out other posts about this?

This one takes falling into account, althought I’m not sure if its the most optimised. You should probably implement both and check whenever the object is touched, along with routine checks at whatever interval.

so handle pick up of objects through touched and also have the heartbeat along side that to prevent players from teleporting to the objects… which makes sense. but what they’re doing is storing a heartbeat for every player… i feel like depending on players that could be stressful and cause lag?

but am not sure if the heartbeats are set up properly with good practice how many heartbeats could you do…

my thinking what to have one heartbeat and then have a task function that handles going through all the players and when task is complete run the task again… this could be once every 0.5 seconds or so so it won’t cause any lag issues… that’s just my thinking though. because what if 50 players were in game ya know. do we want 50 heartbeats?

[UPDATE] research i have been doing on this says that for this specific situation one heartbeat per player would be more useful than just one heartbeat… because the task is specific to each player. so now im wondering if we had 50 players woudl 50 heartbeats cause lag or is it poor practice the way those heartbeats are set up that determine lag?

Couldn’t you just

local RunService = game:GetService("RunService")
local positionTable = {}

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
        local root = character:WaitForChild("HumanoidRootPart")
		positionTable[player.Name] = {
			old = Vector2.new(root.Position.X, root.Position.Z),
			new = Vector2.new(root.Position.X, root.Position.Z),
		}
	end)
end)

game.Players.PlayerRemoving:Connect(function(player)
	table.remove(positionTable[player.Name])
end)

RunService.Heartbeat:Connect(function()
    Wait(0.5)
    
    --Check positions
end)

right but what i’m wondering is if we’re doing one heartbeat for entire server or one heartbeat per player…

I mean it would still pick up if they teleport though wouldn’t it? And if you check on touched then they will get caught anyways. I’d assume multilple heartbeats its less performant but I’m not sure.

It’s mixed but I don’t think its very minor difference in performance anyways.

1 Like

it might be and that’s the main question here i think… because having a task function that loops through all players well that might not be ideal either… because now we’re having to go through all the players (however many there are) and check for each individual. so either it’s like a list (which doesn’t make sense for this situation) or we’re using task.spawn which might be poor practice for this type of situation and may cause be even less performant than multiple heartbeats

So you suggest using task.spawn and putting heartbeat inside it that makes checks? That way you don’t have to loop through a list. Yeh that would make sense but I don’t know which is more performant.

Maybe run some tests in studio?

You could create a system that works to prevent teleports by checking if the distance they moved is ‘walkable’ or not. Basically, you can have a loop that runs every 5 seconds using while wait(5) do and get the humanoid root part position, then you can use their previous position and compare it to their current one using magnitude. Since the walkspeed is Studs/second you can check if the distance exceeds that which they could have moved and if it does, punish them or do whatever you need to do.

Here is what it could look like:

local player = --add the player as a variable, how you do this depends on setup of script (one way could be the player added function, and to have all of this inside that)
local character = player.Character or player.CharacterAdded:Wait()
local prevPos = nil --save the previous position outside the function
while wait(5) do
      if prevPos ~= nil then
          local currentPos = character.HumanoidRootPart.Position
          local maxDistance = (player.WalkSpeed x 5)
          local difference = --Diffrence of currentPos and prevPos using magnitude
          if difference > maxDistance then
              --player is teleporting
          end
      else
          prevPos = character.HumanoidRootPart.Position --function just started, wait for next run to test
      end
end
1 Like

i don’t think using task.spawn would be good for this situation if we were to use a task function and only one heartbeat per server. but i could be wrong.

If you use one heartbeat per server why do you need task.spawn?

this statement is helpful information. in regards to the system we are just going over what the best way to implement it for performance would be. say if we had 50 players in game… would it be affective to use only one heartbeat or multiple heartbeats basically. i personally wouldn’t use a while loop for this just because it makes more sense to use heartbeat.

because what if there are 50 players in game… if we had one heartbeat and didn’t use task.spawn the 50th player would have to wait for the us to check all the other players… which i feel like would not be good. and if we did it this way we’re not creating 50 threads which could cause performance issues. i’m not sure haha. i will do some testing here shortly. wanted to get other people’s experience on the matter before i did.

I’d assume it would be quite quick to loop through though. Even if there is a second delay, if they teleport to an object and touch it the server should still pick that up and do whats necessary (not allow them to interact with the object)

yeah, you may be right but i am trying to prevent that delay if possible.

I’d assume the player wouldn’t notice, especially since theyre exploiting anyways. Besides theres going to be a delay regardless between client and server, just making sanity checks on the object and keeping track of position is probably the most important.

You can but it’s probably overengineering. Unless your game really desperately needs a slight slight boost in performance it’s probably not necessary.

edit: As in when they teleport?

Oh, I already wrote my solution using while loop so ill keep it, however in response to you worrying about using heartbeat and having many players wait until the previous player has been checked, even if you do check the players simultaneously, the server has limited resources so that will just force other tasks to wait. Parallel lua does help speed thing up though, so you could read through luau changes in updates category to see how to optimize things.

1 Like