Any Thoughts on my Anti Noclip Raycast?

I made a very simple AntiNoclip script (Which you can find below), and I want ways to improve it. For example: When a player turns a corner do not mark false positives. Or when a vehicle or moving object / instance gets in between the last known player position, and their current position. I also want to know if this detects false positives.

– *Incomplete code used to be here! Now use the model below.

Here is the AntiNoclip Model:

https://www.roblox.com/library/3082975376/DragRacer31s-AntiNoclip-Huristics-Engine
Please read the code to know where to put it!

The post below me makes me feel kinda dumb. No offence

I also heard that Raycasts can cause a bit of lag, does this script ^^ even ‘Emmit lag’? And how would I improve performance if it does?

11 Likes

If the player is walking through something that they can’t collide with (because CanCollide is set to false), then this script will still trigger.

3 Likes

Resolving False Positives


You should avoid false triggers by adding a folder the ignore list:
local ignore = {script.Parent, unpack(nonCollideableObjects:GetChildren)}

nonCollideableObjects could be a folder that contain all the parts which does not have any form of collision(Cancollide = false).

Alternatively, check the part hit if it has collision or not in the server.

5 Likes

I did add to the if Hit then Statement to detect that. So it ignores non collidable objects.

Is that not the right way to do it?

1 Like

There seems to be an exaggeration of:
Hit.CanCollide ~= false and Hit.CanCollide == true

CanCollide can be either true or false. They cannot have other conditions because of booleans.

3 Likes

You should do HumanoidRootPart:CanCollideWith() instead of a CanCollide check because of custom collision groups.

I think you should also re-cast from where the ray stopped, but with the hit part in the ignore list. Keep doing this until the ray reaches the current position of the player.

5 Likes

How do I use: HumanoidRootPart:CanCollideWith()? I am using it like this:

if root:CanCollideWith(Hit) then

And I seem to be getting an error that I don’t understand.

“Both parts must be PartInstance descendants of the Workspace to make this query.”

2 Likes

Is your character in workspace? Make sure the character is actually parented under workspace first before doing that check. This might be because the character has been created but not parented yet.

(On second thought this doesn’t make too much sense because server-side scripts don’t run when parented to nil…)

3 Likes

Alright I fixed it. Here is what it is now:

if Hit and root:CanCollideWith(Hit) and script.Parent.Parent == game.Workspace then

Edit: Now let me just put that in the first post and it will be good to go!

2 Likes

script.Parent:IsDescendantOf(workspace) works better because you might parent your characters to something other than workspace for whatever reason.

Also you should increase the frequency of your checks to every frame. Characters can easily cut a corner in under 1 second.

3 Likes

I might sound like a total noob at scripting. But how do I exactly make it raycast every frame?

Won’t it be EXTREMELY fast if I make it raycast every frame?

Will it cause performance issues?

2 Likes

Nothing is going to be testable until you fix this:

local RY = Ray.new(LastVec, root.Position)

That’s a ray from the character’s last position, but the ray direction and length are those of the vector from the world origin to the current position. You probably meant:

local RY = Ray.new(LastVec, root.Position - LastVec)

4 Likes

iirc Raycasting is very expensive to do and running it every frame doesn’t seem like a very good idea for game performance but since you asked here is a script that should work.

local runService = game:GetService("RunService")
local event;
local loopConnection;

-- // the reason I do this is because the server does not have a 'RenderStepped' event (and you did not specify if your code was being on the client or server, i have no idea why it would be on the client though but whatever the case)

if runService:IsServer() then
	event = runService.Stepped
elseif runService:IsClient() then
	event = runService.RenderStepped;
end

loopConnection = event:connect(function()
	-- // your script here
end)
3 Likes

Then how often should I run the Raycast / Anticheat ?

Edit: It is server sided. iirc Hackers / Exploiters can’t delete server sided stuff if filtering enabled is on right?

2 Likes

I figured it was server sided lol.
I’ve never really done this type of thing before, so I really don’t know how long you should wait between each raycast. Experimenting with the delay is probably your best bet.

Also, no. Exploiter can delete objects but the deletion will not replicate to the server so it would have no effect on your scripts. (The FilteringEnabled property is basically useless now since Roblox forces it on every game regardless if the property is set to true or false)

2 Likes

One ray per character per frame is not significant. Just replace wait(1) with RunService.Heartbeat:wait(), or (better still) ditch the while loop and connect to the RunService.Heartbeat event.

7 Likes

Why would you want to spam “noclipper” in the chat? I feel like that would be unnecessary flood, would be better off to just kick them.

3 Likes

Just rate limits; a proper debounce should be applied for sending that message right away once, just kick the player(which then disconnects the script) or both.

2 Likes

Are you sure there are no false positives to kick laggy players from the game if it “backfires”?

1 Like

I’m not sure about false positives, a system like this is bound to have them. Over time, your system should get better as it is tuned to stop false positives but not let real problems slip through the cracks.

2 Likes