Source-1-Games icon indicating copy to clipboard operation
Source-1-Games copied to clipboard

[TF2] Holiday Punch And Spy Knife Behind Target Mechanic Not Lag Compensated

Open Marioiscool246 opened this issue 3 years ago • 9 comments

The spy knife and the holiday punch both have a similar mechanic that triggers an event upon if the "is behind target" code succeeds. The knife has the unique backstab instant kill ability and the holiday punch has the ability to force the victim to laugh upon a guaranteed critical hit from behind. The issue with these two weapons is that the code that determines wether you're behind your target ignores lag compensation. The checks for both of the weapons use EyeAngles() on both client and server which ignores lag compensated angles. This issue could be fixed by changing EyeAngles() to GetLocalAngles() only on the server binary while EyeAngles() stays for the client binary. Although this will fix a longstanding issue with knife "failstabs" and the holiday punch not working as it should sometimes, this may increase the likelyhood of complaints of "facestabs" from a laggy spy (maybe this whole issue is why the backstab radius is so large).

Marioiscool246 avatar Jul 08 '22 23:07 Marioiscool246

How did you come to the conclusion that there are differences in lag compensation between the two?

mastercoms avatar Apr 09 '23 19:04 mastercoms

If I remember correctly, when I was testing using GetLocalAngles() for the knife on both the client and server, the clientside crit sound and viewmodel animation from a backstab was incorrectly playing as if the player was always facing the angles of 0, 0 while lag compensation and actual backstab calculations was perfect on the server. Reverting back to EyeAngles() only for the client fixed the angle issue and it perfectly works. Im pretty sure whatever variable that EyeAngles() gets isn't backed up or restored for lag compensation.

Marioiscool246 avatar Apr 22 '23 12:04 Marioiscool246

It seems hooked up to me. Maybe it's another issue with prediction, interpolation or network misalignment, which should be fixed instead.

mastercoms avatar Apr 22 '23 19:04 mastercoms

Yeah that might be worth looking into

Marioiscool246 avatar Apr 25 '23 17:04 Marioiscool246

Went and took a look for myself and it seems like lag compensation for angles only deals with GetLocalAngles and SetLocalAngles (gets m_angRotation). EyeAngles (calls GetAbsAngles which gets m_angAbsRotation) doesn't seem to be backtracked at all for lag compensation which most likely is why this bug is happening.

Marioiscool246 avatar Apr 29 '23 05:04 Marioiscool246

There was a lot of interactions in terms of angle computation between the different angle fields, which is why I wasn't sure.

mastercoms avatar Apr 29 '23 06:04 mastercoms

So I did a re-review of this, and it seems like there were relevant interactions between the two. Abs angles are recalculated upon an update of local angles, and vice versa. So that is fine.

mastercoms avatar Feb 09 '25 04:02 mastercoms

The actual problem is that EyeAngles() for players returns their latest player command's view angle (pl.v_angle). This is then applied to the abs angle (m_angAbsRotation) through the movement command after the move finishes. The player data from their command is not lag compensated. Therefore, backstab code is comparing the latest player command view angles from the victim and the attacker.

One might argue that this is intended to generate a favorable scenario: otherwise players will feel as though they turned around in time (due to unlimited turn rate) and see the Spy backstab them in the face. However, I do think that if the Spy is in their lagged local time, is able to sneak up on someone and get a stab, they should trigger a backstab, regardless of if that is shown as a facestab on the victim's end. Max unlag time and max interp is there for a reason to control the fairness of lag compensation already. Other mechanics can lag compensate headshots behind walls, there isn't any reason spy should draw the short end of the stick.

Therefore, I suggest changing the EyeAngles() code for the victim to GetAbsAngles().

A more disruptive change would be to potentially rewrite the EyeAngles() override for the player to use abs angles in some way on the server, so that the server always uses a lag compensated value for EyeAngles(), or introduce lag compensation backtracking for some parts of the pl player data struct.

mastercoms avatar Feb 11 '25 05:02 mastercoms

I just want to add that my solution to use GetLocalAngles() causes some unwanted side-effects. Now since the tf2 sdk exists, I figured out through experimentation that adding pl.v_angle to the lag compensation save/restore list perfectly fixes this issue.

Marioiscool246 avatar May 22 '25 02:05 Marioiscool246