Bug 2903 - lag compensation (g_unlagged)
Status: RESOLVED FIXED
Alias: None
Product: Tremulous
Classification: Unclassified
Component: Misc
Version: unspecified
Hardware: All All
: P2 enhancement
Assignee: Tim Angus
QA Contact:
URL:
Depends on: 2913
Blocks:
 
Reported: 2006-10-28 17:39 EDT by Tony J. White
Modified: 2006-12-09 14:24:07 EST
0 users

See Also:


Attachments
svn838 unlagged (13.95 KB, patch)
2006-11-09 12:11 EST, Tony J. White
svn838 unlagged (12.58 KB, patch)
2006-11-10 11:16 EST, Tony J. White
svn844 g_unlagged (14.88 KB, patch)
2006-11-15 01:01 EST, Tony J. White
svn848 g_unlagged (17.27 KB, patch)
2006-11-24 14:14 EST, Tony J. White
svn852 g_unlagged (15.35 KB, patch)
2006-11-29 20:04 EST, Tony J. White
svn861 g_unlagged (19.46 KB, patch)
2006-12-07 12:52 EST, Tony J. White
svn865 g_unlagged (20.18 KB, patch)
2006-12-09 14:23 EST, Tony J. White

Description Tony J. White 2006-10-28 17:39:39 EDT
Based on Neil Toronto's Unlagged project:

http://www.ra.is/unlagged/

G_UnlaggedStore()
Whenever a server frame is run (usually every 50ms) record the position data for
for each active client.  Save up to 10 of these markers (or 500ms) for each client.

G_UnlaggedCalc(ent)
Whenever the server processes a command for the client, we look at the serverTime attached to that command and calculate the best guess position for all active clients at that time.

G_UnlaggedOn()
Moves all clients to the positions calculated the last time G_UnlaggedCalc() was run.

G_UnlaggedOff()
Moves all clients back to where they were before G_UnlaggedOn() was run.

For tremulous, most traces that benefit from this happen inside of ClientEvents(), so we wrap that call between G_UnlaggedOn() and G_UnlaggedOff() calls.  Dretch bites, Adv. Basilisk gas, and pouncing are handled outside of ClientEvents, so these calls are added to those functions as well.

This behaviour is toggled with the g_unlagged cvar.

NOTE: this patch hasn't got much testing yet, and no review, so it's probably going to see quite a few changes.  apply with care.
Comment 1 Tony J. White 2006-10-28 17:46:55 EDT
bugzilla is still broken, here's the patch

http://tjw.org/tremulous-svn835-unlagged.patch
Comment 2 Tony J. White 2006-11-09 12:11:01 EST
Created attachment 1141 [details]
svn838 unlagged

* calls to unlagged functions are more fine grained (instead of just 
  wrapping ClientEvents()).  This prevents the issue with people getting
  stuck on a door, etc.  This is from WolfWings.
* Multiple calls to G_UnlaggedOn() before G_UnlaggedOff() is now safe although
  it is not used currently. This is from WolfWings.
Comment 3 Tony J. White 2006-11-10 11:16:34 EST
Created attachment 1143 [details]
svn838 unlagged

* Don't bother with lerping between most recent marker and current position.
  It won't be accurate and it only appears to happen in LAN games anyway.
Comment 4 Tony J. White 2006-11-15 01:01:49 EST
Created attachment 1152 [details]
svn844 g_unlagged

There is a unique problem that comes up with the melee-type attacks of tremulous and unlagged.  Since short range attacks are tied heavily to player movement (unlagged doesn't and shouldn't effect movement), it is very common for an attacker to be put in a position where he either moves over his target's unlagged position or cannot reach it because movement is restricted by their real position.

I've tried a few complex solutions:

1) Use the attacker's unlagged position for the origin of attack.

   This fails because it does not take into account the Pmove of the current
   command and even if the calculated unlagged position were very accurate it
   still feels very clucky since things like impact events are in the wrong
   place.

2) Block player movement from overlapping an unlagged position
   
   This would be very hard to do correctly with Pmove() and even if it were to
   work it wouldn't solve the problem of not being able to reach the target
   if blocked by their real position.

3) Try to detect overlap between attacker and victims unlagged position
 
   Complicated and doesn't prevent the issue of being blocked by a real position
   when trying to hit the targets unlagged position.

The best solution I've come up with is to use a hack: allow the attacker to hit either the unlagged or real position of his target.  In order to make it a bit more fair the range is reduced by half when searching for the real position.  It plays pretty well and considering how deadly unlagged makes the human's hitscan weapons it seems pretty fair.
Comment 5 Tony J. White 2006-11-24 14:14:04 EST
Created attachment 1165 [details]
svn848 g_unlagged


* honour the teleport bit
* instead of doing both traces for melee attacks, collisions are not detected
  with the G_UnlaggedCollisions() function and any calculated position that
  intersects the attackers position will be invalidated.
* account for the built-in 50ms lag on ucmd->serverTime
* account for the built-in 50ms lag when running ET_MISSILE's
Comment 6 Tony J. White 2006-11-29 20:04:28 EST
Created attachment 1173 [details]
svn852 g_unlagged

* forget all that collision crap, simply taking on 100ms (actually 2
  server frames) to the serverTime that the client sends seems to fix this
  issue entirely.  I did some testing with Enemy Territory which has
  the ability to draw bounding box outlines with a server event and it
  seems accurate to do this.  I'm still not sure why this time is so lagged,
  but so far, all testing with this new value has been positive using
  various fake latency values (sv_packetdelay/cl_packetdelay).

I think this is ready for inclusion, but I will give it some more testing
on trem.tjw.org first.
Comment 7 Tony J. White 2006-12-07 12:52:00 EST
Created attachment 1188 [details]
svn861 g_unlagged


* finally sorted out the (cgame Pmove) -> (game Pmove) collision problem
  that's been plaguing unlagged melee attacks.
* used WolfWing's suggestion of limiting trap_LinkEntity() by only
  adjusting other clients who have an unlagged position that is in
  range of the pending trace.
Comment 8 Tony J. White 2006-12-09 14:23:51 EST
Created attachment 1192 [details]
svn865 g_unlagged

* stop adding a server frame time to the ucmd->serverTime
* use unlagged position for calculating the damage modifier

This is committed to SVN as revision 866