Upvote Upvoted 13 Downvote Downvoted
fix for interpolation-based hitbox desync
posted in Customization
1
#1
0 Frags +

many people use custom interp settings depending on their internet connection however there's a problem with some of those

in tf2 (and possibly source engine in general) player lerptime isn't calculated properly. the remainder of cl_interp divided by interval per tick is discarded on the server but not the client. this results in a hitbox desync between client and server hitboxes. here's an example video:

https://www.youtube.com/watch?v=ACgpbDbNi6w

fixing this is quite simple.
your cl_interp value must be a multiply of the server interval per tick (approx.0.01516 for tf2, rounded up) or your cl_interp_ratio / 66 must exceed (or be equal to) your cl_interp.

i tried to get in contact with sigsegv to try and get this bug fixed through valve (reason for it is quite simple, server improperly checks for a bot client).

many people use custom interp settings depending on their internet connection however there's a problem with some of those

in tf2 (and possibly source engine in general) player lerptime isn't calculated properly. the remainder of cl_interp divided by interval per tick is discarded on the server but not the client. this results in a hitbox desync between client and server hitboxes. here's an example video:
[youtube]https://www.youtube.com/watch?v=ACgpbDbNi6w[/youtube]

fixing this is quite simple.
your cl_interp value must be a multiply of the server interval per tick (approx.0.01516 for tf2, rounded up) or your cl_interp_ratio / 66 must exceed (or be equal to) your cl_interp.

i tried to get in contact with sigsegv to try and get this bug fixed through valve (reason for it is quite simple, server improperly checks for a bot client).
2
#2
0 Frags +

is there an easy fix for recommended net settings?
i.e., what ratio would be best for interp 0.033 (hitscan) vs 0.0152 (projectile)

edit: whoops i typo'd yea meant .0303 (30.3 lerp not 33)

is there an easy fix for recommended net settings?
i.e., what ratio would be best for interp 0.033 (hitscan) vs 0.0152 (projectile)

edit: whoops i typo'd yea meant .0303 (30.3 lerp not 33)
3
#3
7 Frags +
bearodactylis there an easy fix for recommended net settings?
i.e., what ratio would be best for interp 0.033 (hitscan) vs 0.0152 (projectile)

basically best way to deal with this is to mess with interp_ratio instead
the way the game actually calculates interp is max( cl_interp, cl_interp_ratio / updaterate )
setting cl_interp to 0 in your config will force it to be at the lowest possible value, which i would recommend
then you can set cl_interp_ratio to 2 (for hitscan) and cl_interp_ratio to 1 (for projectiles) which would give you the ideal interpolation for both, without any desync.

[quote=bearodactyl]is there an easy fix for recommended net settings?
i.e., what ratio would be best for interp 0.033 (hitscan) vs 0.0152 (projectile)[/quote]
basically best way to deal with this is to mess with interp_ratio instead
the way the game actually calculates interp is max( cl_interp, cl_interp_ratio / updaterate )
setting cl_interp to 0 in your config will force it to be at the lowest possible value, which i would recommend
then you can set cl_interp_ratio to 2 (for hitscan) and cl_interp_ratio to 1 (for projectiles) which would give you the ideal interpolation for both, without any desync.
4
#4
3 Frags +
bearodactylis there an easy fix for recommended net settings?
i.e., what ratio would be best for interp 0.033 (hitscan) vs 0.0152 (projectile)

cl_interp_ratio = 2
cl_interp = 2 / 66 = 0.0303

Always round down, so cl_interp_ratio is preferred.

I am pretty sure this 0.033 value that gets thrown around is because someone accidentally dropped a 0 along the way in a recommendation, and that got spread around.

[quote=bearodactyl]is there an easy fix for recommended net settings?
i.e., what ratio would be best for interp 0.033 (hitscan) vs 0.0152 (projectile)[/quote]
cl_interp_ratio = 2
cl_interp = 2 / 66 = 0.0303

Always round down, so cl_interp_ratio is preferred.

I am pretty sure this 0.033 value that gets thrown around is because someone accidentally dropped a 0 along the way in a recommendation, and that got spread around.
5
#5
0 Frags +
mastercomsbearodactylis there an easy fix for recommended net settings?
i.e., what ratio would be best for interp 0.033 (hitscan) vs 0.0152 (projectile)
cl_interp_ratio = 2
cl_interp = 2 / 66 = 0.0303

Always round down, so cl_interp_ratio is preferred.

there's not much point with setting cl_interp to any value other than 0 (minimum allowed by the server) anyway
just set interp_ratio to the amount of ticks you want to interpolate for and you're good to go.
refer to https://github.com/VSES/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/se2007/game/server/gameinterface.cpp#L2425

[quote=mastercoms][quote=bearodactyl]is there an easy fix for recommended net settings?
i.e., what ratio would be best for interp 0.033 (hitscan) vs 0.0152 (projectile)[/quote]
cl_interp_ratio = 2
cl_interp = 2 / 66 = 0.0303

Always round down, so cl_interp_ratio is preferred.[/quote]
there's not much point with setting cl_interp to any value other than 0 (minimum allowed by the server) anyway
just set interp_ratio to the amount of ticks you want to interpolate for and you're good to go.
refer to https://github.com/VSES/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/se2007/game/server/gameinterface.cpp#L2425
6
#6
1 Frags +
navewindrethere's not much point with setting cl_interp to any value other than 0 (minimum allowed by the server) anyway
just set interp_ratio to the amount of ticks you want to interpolate for and you're good to go.

The problem with that is that some servers, more often in competitive server configs, restrict cl_interp_ratio to 1 for some reason.

[quote=navewindre]there's not much point with setting cl_interp to any value other than 0 (minimum allowed by the server) anyway
just set interp_ratio to the amount of ticks you want to interpolate for and you're good to go.[/quote]
The problem with that is that some servers, more often in competitive server configs, restrict cl_interp_ratio to 1 for some reason.
7
#7
2 Frags +
navewindreyour cl_interp value must be a multiply of the server interval per tick (approx.0.01516 for tf2, rounded up) or your cl_interp_ratio / 66 must exceed (or be equal to) your cl_interp.

Afaik it's actually 66.67 tickrate because ticks are exactly 15 ms. Which makes it even more retarded since cmd/updaterate 66 aren't quite correct either. 30.3 is still better than 33 though.

[quote=navewindre]your cl_interp value must be a multiply of the server interval per tick (approx.0.01516 for tf2, rounded up) or your cl_interp_ratio / 66 must exceed (or be equal to) your cl_interp.[/quote]
Afaik it's actually 66.67 tickrate because ticks are exactly 15 ms. Which makes it even more retarded since cmd/updaterate 66 aren't quite correct either. 30.3 is still better than 33 though.
8
#8
2 Frags +
navewindrei tried to get in contact with sigsegv to try and get this bug fixed through valve (reason for it is quite simple, server improperly checks for a bot client).

Try to get them to update the default net settings while you are at it. They are dreadful and probably account for a large portion of the hitreg problems most pubbers exspirience.

[quote=navewindre]
i tried to get in contact with sigsegv to try and get this bug fixed through valve (reason for it is quite simple, server improperly checks for a bot client).[/quote]
Try to get them to update the default net settings while you are at it. They are dreadful and probably account for a large portion of the hitreg problems most pubbers exspirience.
9
#9
1 Frags +

cl_interp_ratio depends on your clients updaterate not the server, so it can also give the wrong value with 0 interp

cl_interp_ratio depends on your clients updaterate not the server, so it can also give the wrong value with 0 interp
10
#10
4 Frags +

lol on ur last example u use 320ms not 32ms

long story short: dont set ur settings to cl_interp 0.0303;cl_interp_ratio 1

lol on ur last example u use 320ms not 32ms

long story short: dont set ur settings to cl_interp 0.0303;cl_interp_ratio 1
11
#11
1 Frags +

thank u nave

thank u nave
12
#12
3 Frags +

Are you sure this bug happens on actual servers with actual players? As far as I can see from experimentally testing it on my test server with participants a few days ago and analyzing the source code, no such bug exists for connected non-bot players.

Are you sure this bug happens on actual servers with actual players? As far as I can see from experimentally testing it on my test server with participants a few days ago and analyzing the source code, no such bug exists for connected non-bot players.
13
#13
2 Frags +
mastercomsAre you sure this bug happens on actual servers with actual players? As far as I can see from experimentally testing it on my test server with participants a few days ago and analyzing the source code, no such bug exists for connected non-bot players.

(in case you're reverse engineering the game) look up CServerGameClients::ClientSettingsChanged in the server.dll of tf2 itself (rather than the source sdk - the code in that is a lot different)

[quote=mastercoms]Are you sure this bug happens on actual servers with actual players? As far as I can see from experimentally testing it on my test server with participants a few days ago and analyzing the source code, no such bug exists for connected non-bot players.[/quote]
(in case you're reverse engineering the game) look up CServerGameClients::ClientSettingsChanged in the server.dll of tf2 itself (rather than the source sdk - the code in that is a lot different)
14
#14
5 Frags +

Not seeing anything faulty there. Everything related to lerp time is a float with no discarding. Also the fact that we experimentally tested it on a server with no issue leads me to believe this only happens on bots.

Not seeing anything faulty there. Everything related to lerp time is a float with no discarding. Also the fact that we experimentally tested it on a server with no issue leads me to believe this only happens on bots.
15
#15
1 Frags +

sorry for bump, but im really confused here. for a hitscan class like sniper where i get good connection (20 ping), should i have cl_interp_ratio 2 and cl_interp 0??

sorry for bump, but im really confused here. for a hitscan class like sniper where i get good connection (20 ping), should i have cl_interp_ratio 2 and cl_interp 0??
16
#16
2 Frags +

Alright, so I did investigate further. CServerGameClients::ClientSettingsChanged is not the source of this issue. TIME_TO_TICKS is. TIME_TO_TICKS converts time in seconds into number of ticks. Number of ticks cannot be fractional, according to the TIME_TO_TICKS formula (equivalent to round(dt / 0.015) in TF2 (full formula is (int)(0.5f + (float)(dt) / host_state.interval_per_tick)).

The two relevant places I could find this being used in relation to interp/lerp is in lag compensation (CLagCompensationManager::StartLagCompensation) and demos. In lag compensation, it uses lerp time (as discussed above, set in CServerGameClients::ClientSettingsChanged), and converts it to number of ticks, and rewinds that many ticks back.

What is confusing to me though is that this seems to use the default tick rate (intervals of 0.015), rather than any networking rates (intervals of 1/66). So I must be missing something, or else most of the default settings or using cl_interp_ratio would cause at least an error as well.

Alright, so I did investigate further. CServerGameClients::ClientSettingsChanged is not the source of this issue. TIME_TO_TICKS is. TIME_TO_TICKS converts time in seconds into number of ticks. Number of ticks cannot be fractional, according to the TIME_TO_TICKS formula (equivalent to round(dt / 0.015) in TF2 (full formula is (int)(0.5f + (float)(dt) / host_state.interval_per_tick)).

The two relevant places I could find this being used in relation to interp/lerp is in lag compensation (CLagCompensationManager::StartLagCompensation) and demos. In lag compensation, it uses lerp time (as discussed above, set in CServerGameClients::ClientSettingsChanged), and converts it to number of ticks, and rewinds that many ticks back.

What is confusing to me though is that this seems to use the default tick rate (intervals of 0.015), rather than any networking rates (intervals of 1/66). So I must be missing something, or else most of the default settings or using cl_interp_ratio would cause at least an error as well.
17
#17
1 Frags +

Thinking about and analyzing it further, an interval of 1/66 in interpolation essentially corresponds to a 0.015 interval on the server. So that's fine.

At 66 update rate, when you receive a new snapshot at for example, 0.04545454545 seconds, and rewind 0.0303030303 seconds back in time for interpolation, you are at 0.01515151515 seconds, which is when you received the packet for server frame 1, so you are rendering server frame 1. So when the server rewinds back to server frame 1, it matches your render position.

But now, it seems like I am missing something else, or there can be a big error on interpolation between packets, because if you shoot someone at 0.05303030302 seconds, your render time will be at 0.02272727272, it will submit a command at 0.0606060606, with tick count of 3. Then, it will rewind two frames back because of lerp ticks of 2 from 0.03030303 lerp, and then use frame 1 on the server, which was 0.01515151515 on client time. So, you see something at 0.02272727272, but the server lag compensates it as if it was on 0.01515151515. Essentially making it compensate for the base tick delay from interpolation, but not the distance interpolation introduces from the base tick values.

Thinking about and analyzing it further, an interval of 1/66 in interpolation essentially corresponds to a 0.015 interval on the server. So that's fine.

At 66 update rate, when you receive a new snapshot at for example, 0.04545454545 seconds, and rewind 0.0303030303 seconds back in time for interpolation, you are at 0.01515151515 seconds, which is when you received the packet for server frame 1, so you are rendering server frame 1. So when the server rewinds back to server frame 1, it matches your render position.

But now, it seems like I am missing something else, or there can be a big error on interpolation between packets, because if you shoot someone at 0.05303030302 seconds, your render time will be at 0.02272727272, it will submit a command at 0.0606060606, with tick count of 3. Then, it will rewind two frames back because of lerp ticks of 2 from 0.03030303 lerp, and then use frame 1 on the server, which was 0.01515151515 on client time. So, you see something at 0.02272727272, but the server lag compensates it as if it was on 0.01515151515. Essentially making it compensate for the base tick delay from interpolation, but not the distance interpolation introduces from the base tick values.
Please sign in through STEAM to post a comment.