Anti Noclip Feedback

So looking true form I did not find much about this, so I took mix idea and turn up with this idea.

--// Service
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local function CanTouchPart(Table)
	for _,Part in pairs(Table) do 
		local Model = Part:FindFirstAncestorOfClass("Model")
		local IsPlayer = Model and Players:GetPlayerFromCharacter(Model)
		if IsPlayer or (Model and (Model.Name =="Frame" or Model.Name =="Block")) then 
			return true
		end
		return false
	end
end

function IsInsideBrick(Position, Brick)
	local v3 = Brick.CFrame:PointToObjectSpace(Position)
	return (math.abs(v3.X) <= Brick.Size.X / 2) and (math.abs(v3.Y) <= Brick.Size.Y / 2) and (math.abs(v3.Z) <= Brick.Size.Z / 2)
end

Players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)		
		
		local Character = workspace:WaitForChild(Character.Name,1)
		local RootPart = Character and Character:FindFirstChild("HumanoidRootPart")
		local Humanoid = Character and Character:FindFirstChildOfClass("Humanoid")

		--// Anti Noclip	
		task.spawn(function()
			while Character.Parent and Humanoid.Health>0 do
				
				local Filter = OverlapParams.new()
				Filter.FilterType = Enum.RaycastFilterType.Blacklist 
				Filter.FilterDescendantsInstances = {Character}
				
				local Parts = workspace:GetPartsInPart(RootPart, Filter)
				if (#Parts)>=1 and CanTouchPart(Parts) then
					if IsInsideBrick(RootPart.Position, Parts[1]) then 
						Player:LoadCharacter()
						warn(string.format("Log: %s // Posible Noclip(%s).",Player.Name,Parts[1]:GetFullName()))
					end
				end
				RunService.Heartbeat:Wait()
			end
		end)
			
	end)
end)

I’d like to know if this could be improved or any other method that could be better.
As been working flawlessly for me as of right now.

1 Like

Seems like you have an unnecessary task.spawn. The script also shouldn’t need to update every heartbeat.

You also have an unnecessary WaitForChild. You should just do the work and disconnect the connection to CharacterAdded.

The OverlapParams can be created in the scope PlayerAdded. You’re creating a new one each frame.

The anti-noclip does not work if there is only one part being noclipped into.

I’ve also found numerous other performance issues and I decided to fix them and post the updated script:

--// Service
local Players = game:GetService("Players")
--local RunService = game:GetService("RunService")

local function CanTouchPart(Table)
	for _,Part in Table do 
		local Model = Part:FindFirstAncestorOfClass("Model")
		local IsPlayer = Model and Players:GetPlayerFromCharacter(Model)
		if IsPlayer or (Model and (Model.Name =="Frame" or Model.Name =="Block")) then 
			return true
		end
		return false
	end
end

function IsInsideBrick(Position, Brick)
	local v3 = Brick.CFrame:PointToObjectSpace(Position)
	return (math.abs(v3.X) <= Brick.Size.X / 2) and (math.abs(v3.Y) <= Brick.Size.Y / 2) and (math.abs(v3.Z) <= Brick.Size.Z / 2)
end

local characters = {}
local connections = {}
local recycle = {}

Players.PlayerAdded:Connect(function(Player)
	local Filter = OverlapParams.new()
	Filter.FilterType = Enum.RaycastFilterType.Exclude
	connections[Player] = Player.CharacterAdded:Connect(function(Character)
		Filter.FilterDescendantsInstances = {Character}
		local newTable = recycle[1] or {}
		newTable.Humanoid = Character:WaitForChild("Humanoid",.5)
		newTable.RootPart = newTable.Humanoid and newTable.Humanoid.RootPart
		newTable.Character = Character
		newTable.Player = Player
		newTable.Filter = Filter
		table.insert(characters, newTable)
		if recycle[1] then
			table.remove(recycle, 1)
		end
	end)
end)

Players.PlayerRemoving:Connect(function(Player)
	connections[Player]:Disconnect()
end)

while true do
	for i, data in characters do
		--// Anti Noclip	
		if not data.RootPart or not data.Humanoid or not data.Character.Parent or data.Humanoid.Health <= 0 then
			table.remove(characters, i)
			table.insert(recycle, data) --Recycle the table! It's faster!
			continue
		end
		local Parts = workspace:GetPartsInPart(data.RootPart, data.Filter)
		if #Parts>0 and CanTouchPart(Parts) then
			if IsInsideBrick(data.RootPart.Position, Parts[1]) then
				data.Player:LoadCharacter()
				warn(string.format("Log: %s // Posible Noclip(%s).",data.Player.Name,Parts[1]:GetFullName()))
			end
		end
	end
	wait(0.2) --Use wait because it throttles unlike task.wait.
end

You should try seeing if this script is faster than what you already have.

I change CanTouchPart to this

local function CanTouchPart(Table)
	for _,Part in pairs(Table) do 
		local Model = Part:FindFirstAncestorOfClass("Model")
		local IsPlayer = Model and Players:GetPlayerFromCharacter(Model)
		if IsPlayer or Part.CanCollide == true then 
			return true
		end
		return false
	end
end

.

i know, i had to change to

if (#Parts)>=1 and (not CanTouchPart(Parts)) then 

.

reason is that is not the only loop in my script, do i only posted about the noclip part for review.
.

I took in consideration what you said and took it out of the loop, ty for noticing.
.
i don’t understand the issue with using task.wait(0.2) over wait(0.2)

the table library as been depreciated.

It’s not deprecated. Only foreachi and foreach are.

It’s not really an issue, but I found that task.wait will not throttle and wait does. If there’s a lot of stuff going on and the server is laggy, wait will wait longer than task.wait to reduce server load, even if it’s not the most accurate.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.