fretta-based game modes and NPCs


I have been working on a custom fretta-based game mode for a while; got quite far, but I am having one large issue that I cannot solve. A friend of mine directed me here for help, so I am hoping someone can help me sort this out.

When I spawn NPCs, such as zombies or antlions, they are unable to successfully melee attack players. They swing as normal, but it does not produce any effect, and the player takes no damage. Projectile attacks work fine, and for some reason headcrabs are able to harm players correctly. The damage-controlling functions built into fretta are not even being called when the non-colliding swings happen, which I find very surprising. (GM:PlayerShouldTakeDamage, etc) The screen does not shake, either.

Initially, I figured this had to be an issue with my game mode, so I began running a diff on files between my game and fretta, but after hours of doing this with no results, I decided to try a much more simple experiment. I copied fretta into a new directory, and added code to spawn an antlion as soon as the player spawns. I was shocked to discover that the antlion could not harm me! I was sure this problem was not present in the normal sandbox mode, so I went to test this, and sure enough, sandbox-spawned antlions were able to hit as normal.

After finding this, I started looking at how the sandbox mode spawns NPCs. I cannot find any major differences between the method there and the one I normally use. I don’t set the initial angles of the monster spawned, but that is the only major difference I could find, and doing this yielded no results.

Additionally, I tried both sandbox and fretta (unmodified) on a map that automatically spawns zombies. In sandbox, the zombies hit just fine. In fretta, they do not. Physics objects they throw hurt, but that is it.

After working with this issue for a few days, and trying to fix it in many ways, I am at a complete loss. So, my question is, why can’t NPCs use melee attacks correctly in fretta-based game modes?

If you want to recreate my example with fretta, just copy gamemodes/fretta into gamemodes/frettatest, then find the following in init.lua:

function GM:PlayerSpawn( pl ) 


	// The player never spawns straight into the game in Fretta
	// They spawn as a spectator first (during the splash screen and team picking screens)

And make it spawn a random monster here. That is, replace that with this:

function GM:PlayerSpawn( pl ) 

	local mons = ents.Create("npc_antlion")

	// The player never spawns straight into the game in Fretta
	// They spawn as a spectator first (during the splash screen and team picking screens)

To try it out, pop open gmod, pick a map, then set the game type to frettatest. The monster will spawn on top of you; use noclip (press the v key) to get out of it, then let it attack you. It will do no damage.

Thank you greatly in advance to anyone who can shed some light on this. I’ve searched the net, compared with various game modes, (Including base and sandbox, of course.) and torn the GMod wiki to pieces, all to no avail, so any help in solving this would be greatly appreciated.

(Also, feel free to move this if you feel it is in the wrong section. I was and still am unsure if this is more fitting to Game Modes or Lua help.)

Well, I took a good few days off before going back at this because it did a good job of annoying me. I found the root of the problem; in my class_default.lua, I had CLASS.TeammateNoCollide = true. Apparently somehow this option caused all NPC melee attacks to no longer hit the player. Changing this option to false remedies the problem.

I am looking now into a better way to fix the problem, but if anyone else is experiencing this, that’s the easy fix!

Edit: The slightly less easy fix is fairly easy too. Make SURE you set CLASS.TeammateNoCollide to false before you do this, or it will probably break in unimaginable ways. Then, add the following function to your shared.lua:

function GM:ShouldCollide( Ent1, Ent2 )
	if (Ent1 != null and Ent2 != null and Ent1:IsValid() and Ent2:IsValid()) then
		if (Ent1:IsPlayer() and Ent2:IsPlayer()) then return false end;
		if (Ent1:IsNPC() and Ent2:IsNPC()) then return false end;
	return true;

This is an override for a function found in base. If you do not care about NPCS, or do not wish for NPCs to be able to pass through each other, get rid of the second if statement.