ValveSoftware / halflife

Half-Life 1 engine based games
Other
3.74k stars 630 forks source link

Some strange weapon prediction behavior #2566

Open SNMetamorph opened 5 years ago

SNMetamorph commented 5 years ago

When I working on my mod, I found out some strange things. I added this piece of code into PrimaryAttack() method:

void CGlock::PrimaryAttack()
{
    ...
#ifdef CLIENT_DLL
    ALERT(at_console, "glock fire %.4f\n", m_flNextPrimaryAttack);
#endif
    ...
}

When I tried to shoot once time on local listen server, it's ok I see this in my console:

cl:  glock fire -0.0010

BUT, when I try it in multiplayer or using fakelag, I see this: With ping 20:

cl:  glock fire -0.0540
cl:  glock fire -0.0410
cl:  glock fire -0.0410
cl:  glock fire -0.0280
cl:  glock fire -0.0280
cl:  glock fire -0.0150
cl:  glock fire -0.0150
cl:  glock fire -0.0010
cl:  glock fire -0.0010

With ping 80:

cl:  glock fire -0.1610
cl:  glock fire -0.1480
cl:  glock fire -0.1480
cl:  glock fire -0.1480
cl:  glock fire -0.1480
cl:  glock fire -0.1480
cl:  glock fire -0.1210
cl:  glock fire -0.1210
cl:  glock fire -0.0940
cl:  glock fire -0.0940
cl:  glock fire -0.0810
cl:  glock fire -0.0810
cl:  glock fire -0.0680
cl:  glock fire -0.0680
cl:  glock fire -0.0680
cl:  glock fire -0.0540
cl:  glock fire -0.0540
cl:  glock fire -0.0280
cl:  glock fire -0.0280
cl:  glock fire -0.0280
cl:  glock fire -0.0010
cl:  glock fire -0.0010

The problem is PrimaryAttack() called multiple times, and the more ping, the more method calls occur. In my mod this breaks melee combos, when player should perform certain number of punches, but due to multiple calls, punch counter totally breaks. I tested this on pure HLSDK code, and problem still occur in it. Also, I tested it on 4554 engine build, and on last Steam engine build (8196), but problem also still occuring.

Why this can occuring? How to fix it?

SNMetamorph commented 5 years ago

I think this also is a reason of bug, when on client side weapon shoots two times instead of one (manifested as double bullet hole decals and two pulled shells instead one).

JoelTroch commented 5 years ago

Potential duplicate of #1621

SNMetamorph commented 5 years ago

@SamVanheer do you know something about this problem?

SamVanheer commented 5 years ago

I looked into weapon prediction event dispatch problems before and i concluded that there were issues in the engine that could cause events to be skipped somehow.

I never managed to figure out what it was exactly that caused it but i suspect the issue there lies with the limit of 64 frames that can be stored for rewinding and playback when resyncing to the server.

As far as events and weapon actions playing multiple times goes this is to be expected. The client will run the same frame multiple times, but animations and sounds are only handled if the engine is telling the client to run functions: https://github.com/ValveSoftware/halflife/blob/c7240b965743a53a29491dd49320c88eecf6257b/cl_dll/hl/hl_weapons.cpp#L1043-L1081

The runfuncs parameter is a boolean that informs client code about this. If you really need to run client side logic then check g_runfuncs to see if it's running the first time.

Note that GoldSource's prediction code is very simple and was slapped on after release so it can't handle complex cases. You should always design your code to use server authorative decisions to avoid issues.

If you need to synchronize state you should use weapon_data_t: https://github.com/ValveSoftware/halflife/blob/c7240b965743a53a29491dd49320c88eecf6257b/dlls/client.cpp#L1585-L1649 https://github.com/ValveSoftware/halflife/blob/c7240b965743a53a29491dd49320c88eecf6257b/cl_dll/hl/hl_weapons.cpp#L660-L1041

This code is all very ugly since it has to operate within the engine's networking system which can't handle arbitrary data like Source or other modern engines can. I used virtual functions to allow for class-specific networking: https://github.com/SamVanheer/HLEnhanced/blob/3e763c1083122fd91ae197178f0b97976b224ba8/game/shared/entities/weapons/CBasePlayerWeapon.h#L228-L238 https://github.com/SamVanheer/HLEnhanced/blob/346a9889f7da589f72cc66a71ee1202fc434714a/game/shared/entities/weapons/CHandGrenade.h#L46-L60 https://github.com/SamVanheer/HLEnhanced/blob/346a9889f7da589f72cc66a71ee1202fc434714a/game/server/client.cpp#L881-L921 https://github.com/SamVanheer/HLEnhanced/blob/346a9889f7da589f72cc66a71ee1202fc434714a/game/client/hl/CClientPrediction.cpp#L125-L450

Regardless you will find it difficult to handle stuff on the client side without glitches if it requires multiple sequential events.

SNMetamorph commented 2 years ago

@SamVanheer do you have some new info about this event double playback issue, please?

SamVanheer commented 2 years ago

See #1621, that's probably what causes this as well.