Anti-lag and tab glitch script that I believe should be implemented by default

I was looking around trying to find a way to eliminated tab glitching, when I came across this post. The code in the post was very flawed, and you can not risk kicking someone if they have a ping spike, so I created my own script which, instead of kicking you, sets the network owner of your character to the server when it detects you are tab glitching/lagging, eliminating floating in the air.

Code:

local Players = game:GetService("Players")


-- // Anti Tab Glitch
Players.PlayerAdded:Connect(function(Player: Player)
	local t = 0
	local bfr = 0
	local anti = false
	Player.CharacterAdded:Connect(function(Character)
		task.spawn(function()
			while wait(0.01) do
				--print(Character.PrimaryPart:GetNetworkOwner())
			end
		end)
		t += 1
		if t == 1 then
			wait(10) -- Players who just join the game will get a grace period for game to load
		end
		local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
		local Humanoid = Character:WaitForChild("Humanoid")
		local _L = coroutine.create(function()
			while task.wait() do
				local OldPosition = HumanoidRootPart.Position
				local OldVelocity = HumanoidRootPart.Velocity

				task.wait(Player:GetNetworkPing() + 0.05 + bfr)-- Added 0.05 in case ping is very low somehow so script wont get overloaded--task.wait(.5) -- // Amount of time allowed in air. (.15 works well)
				bfr = 0
				local CurrentPosition = HumanoidRootPart.Position
				local CurrentVelocity = HumanoidRootPart.Velocity 

				if OldPosition == CurrentPosition and OldVelocity ~= Vector3.new(0,0,0) and CurrentVelocity ~= Vector3.new(0,0,0) and Character.PrimaryPart:GetNetworkOwner() == Player then
					Humanoid.WalkSpeed = 0
					Humanoid.JumpPower = 0

					Character.PrimaryPart:SetNetworkOwner(nil)
					anti = true
					repeat task.wait() print(HumanoidRootPart.Velocity.Magnitude) until HumanoidRootPart.Velocity.Magnitude <= 1 -- You are prevented from being able to move so your character is able to fall if its floating then it will let you move again.
					Humanoid.WalkSpeed = 16
					Humanoid.JumpPower = 50
					anti = false
				elseif Character.PrimaryPart:GetNetworkOwner() == nil then
					Character.PrimaryPart:SetNetworkOwner(Player)
					bfr = 1
				end
			end
		end)
		coroutine.resume(_L)

		-- // Prevent's kicking when player is dead.
		Character.Humanoid.Died:Connect(function()
			coroutine.close(_L)
		end)
	end)

end)

Anyways, let me know what you guys think of this, and if there is anything I could improve.

4 Likes

wait is deprecated using task.wait would be better

{CC741658-740F-48BA-BA11-DC6C37C01DC2}

there is no need to type 0.01 in the wait function as it will still wait for 0.03

if you cleaned up the code, removed magic numbers (what if loading takes longer than 10 seconds?) and removed unused parts that would be way better

Couldn’t you just use Player.CharacterAdded:task.wait() to wait until the player has loaded?

wait was just easier to type and that was just test code so I can see it printing, it doesnt matter.

edit: I saw that wait(10) wasnt task.wait(10), but I should remove this code and do something else anyways

Yes, but then the physics don’t start on the character until a few seconds after its added, so the game will think you are tab glitching. You ever see someone float for a moment when they join you on roblox then fall?

Ok, thank you for the suggestion. Do you have any idea what I could possibly replace “wait(10)” with

I will post and updated version without magic numbers to here soon!

That’s a good point, didn’t think about that.

idk. first thing i come up with is adding a loading screen, so the character wont be loaded (Players.CharacterAutoLoads) while assets aren’t loaded.

BUT the one i suggested seems complicated to me

I don’t think you can call task.wait() on an RBXScriptSignal. Try RBXScriptSignal:Wait() instead.

2 Likes