My ShouldCollide code is breaking the game physics

In my gamemode’s shared.lua:

function GM:ShouldCollide( ent1, ent2 )

	// Players that are stuck in each other, like after spawning
	if (ent1:IsPlayer() and ent2:IsPlayer()) then
		local ent1pos = ent1:GetPos()
		local ent1obbmin = Vector(-16,-16,0)*0.95
		local ent1obbmax = Vector(16,16,72)*0.95
		local entl = ents.FindInBox( ent1pos+ent1obbmin, ent1pos+ent1obbmax )
		if (table.HasValue(entl, ent2)) then 
			local normal = (ent1:GetPos()-ent2:GetPos()):GetNormal()
			if (math.abs(normal.x) < 0.2 and math.abs(normal.y) < 0.2) then normal.x = 1 end
			ent1:SetVelocity( normal * 70 )
			ent2:SetVelocity( normal * -70 )
			return false
	return true

Basically what it does it pushing two stuck players away from each other. There’s a strange issue however that occurs when I test on a listen server with bots. If this code gets called ‘too often’ (doesn’t seem to happen directly) the physics engine seems to break and all physics props start acting like the ground is made of water or something.

Recording here: (12MB gif)

The physics remain broken even after starting a completely different map and gamemode. I can’t fix it without restarting Garry’s Mod completely.

I have heard that this happens if different values are returned for the same 2 objects.

I had this in portal, except shit went through the roof, instead of the floor.

Try not to return true.

remove return true at the end of your code.

If you return different values between two same entities - you can break physics engine.

Gah, it’s also stated on the wiki. Thanks for the help guys.


Also removing ‘return true’ breaks the physics directly. Have to return something. I’ll just cache the result between entities or something.


Can’t really fix this because you can’t really predict whether it’s going to return true or false for entity set and use that for when it’s called the other way around.

You really shouldn’t be doing the pushing inside this hook. In fact, I believe you shouldn’t be using this hook at all for what you are trying to do. Changing a collision in real time like that causes the physics to break. You should really look into an alternative method.