Shpoike / Quakespasm

Extra bloaty junk to modernise stuff a bit.
http://triptohell.info/moodles/qss/
GNU General Public License v2.0
184 stars 41 forks source link

sv_nqplayerphysics default value #129

Closed VinnyVicious closed 9 months ago

VinnyVicious commented 9 months ago

Why is the default value of sv_nqplayerphysics 1? Shouldn't prediction always be enabled? Are there any issues with it?

Shpoike commented 9 months ago

prediction reworks a lot of general things surrounding the physics. One change being that it makes the players think independently of every other entity, and moves the player acceleration/friction/etc logic into the logic between PlayerPreThink and PlayerPostThink instead of being separate. This results in issues in mods that make such assumptions. By leaving it disabled nothing is broken by default.

Plus there's the small matter of prediction using QW player physics instead of NQ player physics, and basically everyone in either community assuming that the other community is full of uncultured morons. There are differences and there are expectations - and as an NQ engine running NQ mods the default should match other NQ engines in order to not break those expectations too badly.

Also, QSS does not attempt to undo the velocity changes inside client.qc (eg there's some extra water drag in there), which should be the only real issue with vanilla quake iirc. Any mod that actually cares about prediction will remove those and implement the SV_RunClientCommand function (even if all it does is call the runstandardplayerphysics builtin), and by defining that function the mod will cause the engine to ignore the sv_nqplayerphysics cvar anyway.

Besides, there's always paranoia around large additions. Sometimes it just takes time to get the confidence to enable it by default. By all means try it though.

VinnyVicious commented 9 months ago

I had no idea about SV_RunClientCommand. For anyone reading this from the future:

Prediction:
In theory, prediction is easy. Simply keep an input frame log, track which input frame was the last one applied to movement data, and applay any unacknowledged input frames to the last state received using the same logic that the server will use.
In practise, prediction is not reliable. It is a guess. A guess which is not particuarly compatible with traditional NQ player entity physics frames with their lack of syncronisation or even acknowledgements.
Generally this means that you must implement ALL player physics code yourself, using tracebox. Alternatively you may be able to get away with using the engine's runstandardplayerphysics function instead, modifying the various input_* values slightly before calling it.

From the SSQC side, things are fairly simple. The server calls:
void() SV_RunClientCommand =
{
    input_angles_y += 180;      //a fun mindfuck.
    runstandardplayerphysics(self); //and apply the input frame to the current entity state.
}:

From the CSQC side, when you receive an entity state the servercommandframe global will say the input frame number that was last acknowledged by the server. Thus any player entity from the server will have this input frame already applied. While the clientcommandframe global is the input frame that is currently being generated.
Thus if 'self' has its fields set to the most recently received state, you can apply all pending input frames with:
for (if = servercommandframe+1; if <= clientcommandframe; if+=1)
{
    if (!getinputstate(if))
        continue;       //that input frame is too old.
    input_angles_y += 180;      //a fun mindfuck.
    runstandardplayerphysics(self); //and apply the input frame to the current entity state.
};
The input frame that matches clientcommandframe is updated each frame, until it is finally sent at which point the global is bumped. Input frames will not be remembered forever, but will otherwise be static until they are forgotten.
You can then set the VF_ORIGIN view property to match the predicted position. You will also likely want to smooth out steps, and perhaps add error correction too.

Sample: https://github.com/parhelia512/FreeCS/blob/ec41057c4e611dacfa14fd4519111afff2fc8dce/Source/Server/Client.c#L123

https://github.com/shpuld/CleanQC4FTE/blob/aa7dfd7711a4e05d4fbfeb8014309da32d9cf846/server/player.qc#L229