Prevent players no-clipping through terrain?

In my game I have a maze of tunnels which are made out of SmoothTerrain. Some players have the ability to no-clip through terrain though (e.g. glitch, exploit, etc) which ruins the secrecy and fun of the maze.

What’s the best way to prevent them doing this?

One way I think I could prevent this is by checking if a player’s whole body is in terrain, check the terrain is not water, then kill them. However, I am not sure how I would script this.

Any ideas? Thanks.

1 Like

You could shoot a ray from the player’s torso/uppertorso downward about a fourth of a stud, and it if hits something that’s not water or the player, kill them or TP them somewhere.

1 Like

Another method:

Create invisible dots through the maze using very small parts.
When the player is inside the maze, check the magnitude distance between the player and these parts.
If it detects that the player isn’t near any of them but they are inside the maze, teleport them to the beginning.

4 Likes

I haven’t done this before, but with filtering enabled you may be able to call http://robloxdev.com/api-reference/function/BasePart/SetNetworkOwner with no arguments to set the ownership of players’ character’s parts to the server. This may cause slight delays in movement though.

To create a comprehensive solution I’d write my own character controller which just moves the character locally when a button is pressed, but the movement is repeated on the server and that is what gets sent to the other clients. It should also send updates back to the player’s controller to correct any discrepancies.

do not do this, it’s horrible ux

I would go with shooting a ray from the humanoidrootpart every so often that wouldn’t exit the torso and seeing if it hits anything (using the character as a blacklist)

3 Likes

I just thought of this out of nowhere.

So you make a new part and weld it to the Character’s Head like a little bit on top if it, the Part will be parented to workspace or a folder BUT NOT the Player’s Character and then you detect if that Part Touches anything it shouldn’t but make the part really small so it has to be inside the walls (or terrain) to be touched.

or

You can use Humanoid.Touched ?

@PressurizedSphere @Starception

I tried this, but even when noclipping through the terrain, the ray registers it as Enum.Material.Air
I also tried varying the distance between 0.25 and 2 but it still records the same:

local player = game.Players.LocalPlayer

while wait(0.5) do
	local character = player.Character
	
	if character then
		local start = character.UpperTorso.CFrame.p
		local lookAt = (character.UpperTorso.CFrame * CFrame.new(0,-10,0)).p
		local ray = Ray.new(start, (lookAt - start).unit*2)
		
		local part, position, normal, surface = workspace:FindPartOnRay(ray, player.Character, false, false)
		print(part)
		print(surface)
		print()
	end
end

That’s a nice idea, thanks, but would take too long for me to do, unless I can figure out a way to automatically generate the dots!

Do not do this. There is a reason player characters are owned by their respective clients. The delays won’t be slight, and the game will provide an insufferable experience to players. Games that handle movement on the server (e.g. Halo) do a lot of optimization and magic behind the scenes to make this feasible. Just setting network ownership is not good enough.

This is making the OP’s problem much more difficult than it needs to be. We need to be able to detect when people noclip to respawn/kick them – not spend 90% of development time writing some convoluted character controller from scratch.

2 Likes

There are two approaches here. You can prevent players from going through terrain or you can remedy it when it happens. If you want to prevent it, it must be done server side. This means making the server in some way own the logic. My first proposed solution I knew to be naïve, which is why I followed it up with the proper way to do it (I basically described a simplified version of player movement in the industry). To remedy it you need some way to determine when the player is outside bounds. I’d try using Terrain:ReadVoxels() to determine if the cells containing a percentage the AABB of the character are filled or not (maybe 100% or 50%, depending on the sensitivity you want). This’ll probably be cheaper than ray casting and not require creating/generating a custom graph like the sphere suggestion above.

1 Like

This used to happen to me ALL THE TIME , in my Neverland Lagoon game, especially with any character that had a modified size for their HumanoidRootPart.

It isn’t a game breaker situation in my game, so now that it happens a lot less, I don’t bother with it, however, back when it was a real issue for me, I tried several solutions, and the one that was most effective, and easiest to implement was welding a 4x4x4 invisible block onto the players HRP.

Hope that helps.

1 Like