Remix.run Logo
BoingBoomTschak a day ago

Talking about Unlagged, I would kill for a clear explanation (with diagrams!) of various netcode improvements in it, CPMA and QL.

I'm forced to try to piece together a mental model by finding crumbs on the web, with the current situation:

https://github.com/minism/fps-netcode

https://playmorepromode.com/guides/cpma-client-settings

https://www.esreality.com/?a=post&id=2548041#pid2548771

https://old.reddit.com/r/QuakeChampions/comments/9jd3wv/for_...

PS: the modern way of enjoying Q3 is https://github.com/ec-/Quake3e or CNQ3, these days. Don't know about https://github.com/ioquake/ioq3

monkburger a day ago | parent [-]

I can't speak for CMPA or QL, but I can speak a little bit on Unlagged:

- w/ Unlagged, the Server now stores a history buffer (g_activeSnapshots[]) of player states. When processing a action shot, it uses the timestamp sent by the client (cmd.serverTime) to interpolate or rewind states for collision checks (G_EvaluateTrajectory()). This allows the server rewinds player positions to the moment a client action occurred (eg: firing a shot)

- Unlagged reduces choppy movements by making clients use a snapshot buffer (cg.snap, cg.nextSnap) to interpolate positions with CG_InterpolateEntityPosition(). Extrapolation uses velocity vectors from the last known snapshot (currentState.pos.trDelta).

- Unlagged tries to compensate for high latency by rewinding entities to their positions at the time of the shot (ClientThink_real() and G_RewindEntities()). Uses a circular buffer (via lagometerSnapshot_t) to store past states.

- Position corrections (cg.predictedPlayerState) are interpolated over several frames using VectorLerp() to fix prediction mismatches between client and server.

- Commands are stored in a circular buffer (ucmds[]) and replayed when missing packets are detected (ClientThink_cmd()). This attempts to mitigate packet loss by buffering input commands for later execution