Anti Teleport System

Hello! Before you say, “this post has been made a million times,” I know. I have read over ten dev forum posts on this, and nothing seems to fit my liking.

What do I want to achieve?
I want to make a anti-teleport system that does the following:

  • Allows the player to fall
  • Make it so the exploiter cannot put themselves in a falling state to bypass tp
  • Allows in-game teleports to still function
  • Does not affect high ping players

What have I tried so far?
I have looked at a lot of posts, and they all use magnitude, so I thought I would do this too. Here is my code:

game.Players.PlayerAdded:Connect(function(Player)
    debounce = false
    Check = false 
    humanoidrootpart = Player.HumanoidRootPart
    maxDistance = 50 --I will mess around with this when the script works how it should.
    game:GetService("RunService").Heartbeat:Connect(function()
        if humanoidrootpart then
            if Check == false and debounce == false then	
                debounce = true
                LastPos = humanoidrootpart.Position	
                wait(.1)
                Check = true
                debounce = false
            else
                if debounce == false then	
                    local NewPos = humanoidrootpart.Position	
                    if (LastPos - NewPos).Magnitude > maxDistance then
                        Player:Kick("Teleported.")
                    end	
                    Check = false
            end
        end
    end)
end)

This code doesn’t help with high ping players, and doesn’t prevent a player from getting kicked if they are falling.

What other posts have I looked at?
The best post I have found is this: Anti TP Exploit - #6 by Operatik

That post covers anti exploits, but can still affect players falling, and laggy players.

Another thing is, I would need to make a second thing like this that tracks the players total distance over a total of ten seconds. The reason for this is that the player could easily make themselves teleport a bit at a time over and over again. This would totally counter this system.

The tricky thing is exploiters can do so much, and you are never safe. The best we can do is prevent a couple big things like teleporting. If you can help, please leave a reply. I am not asking for an entire script, just how I would do the things I want to achieve.

(This is my first post ever, how do you think I did?)

Personally, I would store the players position every minute and then store there new position after another minute. Then just make sure the magnitude of those two positions arent too big.

To make this functional with your teleports you can update the players last saved position everytime they teleport.

1 Like

Yeah, I think this sounds like a great solution. However, it would be hard to prevent the script going off if the player is falling. I think I could, but even then the hacker could just make themselves in a “falling” state and be unaffected.

When storing the players position only store the X and Z values and just set the Y to 0 every time. That would mean it wont take into account the height travelled.

Okay, I could do this. But couldn’t this still affect high ping players?

To make this functional with your teleports you can update the players last saved position everytime they teleport.

Well, I would want the anti-teleport script in server script service, and I would prefer not to have to make the teleporter’s function in server script service too. I could store the last position inside the player as a string, would this function well or is there a better solution?

You can do it all from a server script. Just store the players positions in a dictionary inside the script like so

local positions = {
  ["johnyTest"] = {
    ["Position1"] = Vector3.new(10,0,10);
    ["Position2"] = Vector3.new(40,0,30);
  },
  ["Billy"] = {
    ["Position1"] = Vector3.new(10,0,10);
    ["Position2"] = Vector3.new(40,0,30);
  },
}

Sorry if I was unclear. I was asking how I would end up setting the last position to the current one when the player teleports. How would I do this and connect between scripts? Like I said, I could use string values in the player, would that work?

You can have bindable events which fire when the player is teleported and that event will be picked up inside the anti teleport script which will then update the players saved position(s)

1 Like

Thanks! I will let you know what I come up with later and tell you if I need any other help with the code.

1 Like

@trackysecretagent
I have a script! Are there any improvements I should make?

local PosTable = {}

--Set position on load
game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function()
		wait(2) --Just in case
		PosTable[player.Name] = {
			["Old"] = Vector3.new(player.Character:WaitForChild("HumanoidRootPart").Position.X, 0, player.Character:WaitForChild("HumanoidRootPart").Position.Z);
			["New"] = Vector3.new(player.Character:WaitForChild("HumanoidRootPart").Position.X, 0, player.Character:WaitForChild("HumanoidRootPart").Position.Z)
		}
	end)
end)

--Remove position when left
game.Players.PlayerRemoving:Connect(function(player)
	table.remove(PosTable[player.Name])
end)

--When teleporter fires I will not get kicked for "hacking"
game.Workspace.TP.Event:Connect(function(Player)
	PosTable[Player.Name]["Old"] = Vector3.new(Player.Character:WaitForChild("HumanoidRootPart").Position.X, 0, Player.Character.HumanoidRootPart.Position.Z)
end)

--Check position every 10 seconds
while wait(10)do
	for i,v in pairs(game.Players:GetPlayers())do
		local old = PosTable[v.Name]["Old"]
		local new = PosTable[v.Name]["New"]
		
		new = Vector3.new(v.Character:WaitForChild("HumanoidRootPart").Position.X, 0, v.Character:WaitForChild("HumanoidRootPart").Position.Z)
		
		if old and new then
			print((old-new).Magnitude)
			if (old-new).Magnitude > 450 then --Need to mess around with the 450
				v:Kick("Exploit detected.")
			end
			
			old = Vector3.new(v.Character:WaitForChild("HumanoidRootPart").Position.X, 0, v.Character:WaitForChild("HumanoidRootPart").Position.Z)
		end
	end
end

Now I have a few questions:

Is there a way I can simulate high ping to check if this affects these kinds of players?
Is there any security flaws in the code, if so how do I fix it and what is the issue?
Is there harm in any way making a post with this code in it that could bring threats to my game?

What I want to add:

A three strike system. When a player is caught cheating they will be kicked and they will gain one strike. If they continue they will get more strikes. If they get 3 strikes they will be auto banned. After three days the strikes disappear for anybody not banned, this will prevent one time bugs from getting an active player banned. (Is an auto ban too much? I plan to test this out for a while to make sure everything works well. I will have to see what happens with high ping players.)

Thank you! If you could, please leave a note on each question and any suggestions.

That looks great! I’m not sure what issues could arise with the script with high ping issues so there wouldn’t really be a need to simulate high ping players.

On the remote event connection. An exploiter can just fire that event then it would update their saved position.

What I suggest is have a boolValue in the player called canTeleport and set the value to False. When teleporting a player, you will set the value to True and change the code to this:

game.Workspace.TP.Event:Connect(function(Player)
    if not player.canTeleport.Value then return end
    player.canTeleport.Value = false

	PosTable[Player.Name]["Old"] = Vector3.new(Player.Character:WaitForChild("HumanoidRootPart").Position.X, 0, Player.Character.HumanoidRootPart.Position.Z)
end)

This would then only allow the players saved position to be updated by this remote event when the canTeleport value has been set to True.

This is a bindable event, not a remote event. I believe this cannot be fired by the client. Is this correct?

You’re right. My bad, I for some reason thought it was a remote event.

1 Like