Keeping players from teleporting themselves in game

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

Isn’t character appearance loaded ran when everything is parented to the character?

I haven’t heard of this before so I’m not sure but if you really need it optimised then this is probably what you should do.

it seems i was wrong about character appearance loaded. it only runs when the character’s appearance is loaded on character added basically.

yeah i’ll just do the one heartbeat for now to handle checking distance and comparing to walkspeed.

Unrelated but this seems pretty cool, I’m probably going to use it for my game now.

1 Like

A predominant reason for using the Heartbeat is that it wont cause for your game to yield or lag. As Heartbeat is not an operation that requires to be completed in the lifecycle you can do this operation multiple times - that being said a lot of Anti-Teleport systems are generically quite flawed as it will all be dependent on the time taken and the methodology used to travel.

Gravity in the game for example is in reference to 9.8m/s so you’d have to handle these occasions also.

In my opinion, the simplest way of stopping someone from teleporting is to simply make a game design which doesn’t reward cheating.

Example: Destiny 2
A key way that this game prevents exploiters and glitchers, which is a large sum of players (who predominantly glitch) is to make checkpoint systems and use what I will simply refer to as “gateway logic”.

What his essentially means is that the player must do a bunch of pre-requisites to trigger an event. If they try to trigger these events without it then frankly they cannot advance.

Now what is “Gateway Logic” as I refer to it:

Lets establish some facts:

  • Exploiting is like playing a game.
  • Their game is simple, they get what they want and you must suffer.
  • You are a pawn in their game, and you’ll remain a pawn until you choose to play the game.
  • The rules to this game are clear: You take what they give you, give away what you have to - then the difference is yours.
  • The main question for you is “how big is the difference”.

Exploiters are not clever individuals, what they do is get banned and banned again until eventually they make an exploit which lets them win.

They will give away their tools, and it is your job to patch such tools. What you must do however is make a tool which drains the fun out of them.

So how do you beat the exploiter:

  • You know how long it takes to complete your game,
  • You also know the likeliness of how often things will happen.
  • You also know how things act and the pathways to your game.

With these 3 simple pieces of information you can create 3 checks:

  1. Did the user complete the entire thing in a time unconceivable to the user. This can simply be done by finding the fastest time possible from A to B and comparing yourself to it - did they get to the gateway in a normal time or not.
  2. Did the user do it in such a way that would be unlikely for a person of their ability, for example did they just skip across areas - did they try and cheat the gateway by avoiding sections.
  3. Did they actually follow the game routing and do all the steps to get from A to B - going through the gateways.

If a player clicks the “I win” button at the end, but theirs no way they can be there, they cheated.

I would not waste your time trying to patch everything an exploiter does, but instead patch people breaking your game lifecycle.

1 Like