Message Boards

 Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - Dr. Sean

Pages: [1]

Devoblog / Network-related Client CVARs

« on: May 17, 2014, 18:10:21 »
Network-related Client CVARs

Note that these apply to Odamex 0.7 and may change in future versions!

rate ("Bandwidth" in the Network Options menu)
Sets the maximum bandwidth the client can receive, measured in kilobytes per second. The default value is 200, though setting it higher to 750 will allow for faster in-game downloading if the server allows it.

cl_unlag ("Adjust weapons for lag" in the Network Options menu)
Allows the client to enable or disable backwards reconciliation ("unlagged") for hitscan weapons. Enabled by default, this setting allows a player to aim directly at enemies when firing hitscan weapons such as the shotgun and chaingun.

It works as follows:
  • Every gametic (there are 35 per second), the server records the position of every player.
  • When the server sees that a player with round-trip latency of X milliseconds pressed the fire button, it temporarily moves all other players to the position they were in X milliseconds ago.
  • The server determines if the shot hit anyone.
  • Players are moved back to their current position.

cl_updaterate ("Position update freq" in the Network Options menu)
Indicates the frequency of position updates a client wishes to receive. The default value of 1 indicates they wish to receive an update every gametic while a value of 2 indicates an update every 2 gametics. More frequent updates lead to greater accuracy at the expense of more bandwidth usage.

cl_interp ("Interpolation time" in the Network Options menu)
Allows a client to smooth the movement of enemy players due to network jitter in the connection between that particular client and the server. This smoothness comes at the expense of increased visual latency.

If the most recently received position update is N, the default value of 1 will display players at position update N - 1. Similarly, a value of 2 will display players at position update N - 2.

Network jitter causes the client to not always receive position updates in a timely manner. If a client displayed position update N - 1 last gametic and has yet to receive a new position update from the server, it can display position N, maintaining accurate, smooth movement even when there is jitter or small latency spikes.

Allows the client to enable or disable client-side prediction of a client's player position. This prediction, enabled by default, allows the client to immediately move its player position based on controller input instead of waiting for confirmation of a new position from the server. This is much more responsive compared to the alternative, which does not change the player position (and in turn the rendered view of the world) until the the client's round-trip latency time to the server has passed.

Although prediction allows for immediate visual feedback, it can also be incorrect. This is often the result of collision with other players or being thrust by weapon damage. When the prediction is incorrect, the client considers the server to be authoritative about the real position of the client's player.

Although most players would find it difficult to play with this CVAR disabled, it is immensely useful in diagnosing recordings of games for debugging purposes.

cl_prednudge ("Smooth collisions" in the Network Options menu)
Sets the amount of interpolation between a client's mispredicted player position and the corrected player position from the server. Valid values range from 0.05 to 1.0. The client can choose how they want to trade off between smoothness and accuracy when their player position is mispredicted (see cl_predictplayerposition for further background information). A value of 0.05 will nudge the player towards the correct position gradually and as smoothly as possible where as a value of 1.0 will instantly jerk the player to the correct position to be as accurate as possible.




Devoblog / Overview of Hitscan Latency Compensation (Unlagged)

« on: May 17, 2014, 15:51:48 »
Hitscan latency compensation is a topic that causes a great deal of confusion as to how it works and what side effects are to be expected. The community has long ago adopted the term "unlagged", which in itself is a source of confusion but hopefully this post can clarify several points. For further detail on the topic, please read this excellent overview by Valve, from which Odamex's algorithm was derived.

For the examples in this explanation, we will consider two players: Player A with a 150ms ping and Player B with a 20ms ping.

Background info:
Odamex has a fixed frame-rate of 35fps, which means each frame lasts roughly 29ms. That also conveniently corresponds to the network update rate and the game physics update rate.

Odamex also uses a term "world index" to refer to the particular set of actor positions that the client has received from the server and uses to draw the sprites for actors in the game (enemy players, etc).

How it works:
When Player A aims directly at Player B and presses the fire button, his Odamex client will send all of his input (eg, fire-button, mouse angle, etc) to the server as well as the current world index. The server will receive this input from Player A 75ms later. During this time, Player B may have moved significantly and without latency compensation, Player A would miss his shot.

With latency compensation, the server will temporarily move all players except the shooter to their position in the world index that was received from the shooter. In the case of Player A shooting, it means that Player B would be moved to his position 150ms ago. The server then performs hitscan collision detection and then moves all of the players back to their current real position. This compensation allows Player A to aim directly at Player B and successfully hit him, even with adverse network conditions.

One side effect of this compensation can be seen from the point-of-view of Player B. It is possible for Player B to have gotten behind cover of a wall and still be shot by Player A. This is due to the fact that Player A has high latency and thus his input takes a noticeable amount of time to reach the server and during this time, Player B can move behind a wall. The latency compensation will temporarily move Player B to his position at the time Player A pressed fire, which was directly in the line-of-sight of Player A.

Hopefully this description is not too technical and also did not omit any details that are necessary for understanding the way latency compensation works in modern FPS games. Let me know and I can further clarify any points which are not clear.

Devoblog / Netcode White Papers / Videos

« on: September 17, 2013, 17:55:40 »
As players often wonder how Client/Server games work "under the hood", I'm creating a small thread that lists some important white papers in the field of client/server game programming.

This paper describes the architecture of the TRIBES engine and subsequent TNL library.
Video and slides for similar information:

This paper describes Doom 3's architecture, which is an advancement over Quake 3 Arena.

This paper describes the CounterStrike architecture and the specifically client prediction of position and latency compensation for weapons.

This video describes Halo's architecture, which is based heavily on the TRIBES architecture.


General Discussion / Setting up SR-50

« on: August 05, 2013, 19:33:13 »
This guide assumes a player is using the common WASD configuration for their movement keys, configured with the following:
Code: [Select]
bind W +forward
bind S +back
bind A +moveleft
bind D +moveright

Players should choose the method that they feel comfortable with, modify the key binding to match their movement layout, and then paste into the bottom of odamex.cfg.

Old School
Usage: The player will SR-40 to the right with W & D and then SR-50 by holding down the second mouse button and moving the mouse continuously to the right.

Code: [Select]
bind mouse2 +strafe
set m_side 15

Three Key
Usage: The player will SR-40 to the right with W & D but will also hold down a third key, Q, to SR-50 to the right. Similarly, the player will hold down W & A & E to SR-50 to the left.

Code: [Select]
alias +sr50l_3key "+left\;+strafe"
alias -sr50l_3key "-left\;-strafe"
alias +sr50r_3key "+right\;+strafe"
alias -sr50r_3key "-right\;-strafe"
bind Q +sr50r_3key
bind E +sr50l_3key

Two Key
Usage: The player holds down W to move forward and then holds down a second key, E, to SR-50 to the right, or Q to SR-50 to the left.

Code: [Select]
alias +sr50l_2key "+left\;+moveleft\;+strafe"
alias -sr50l_2key "-left\;-moveleft\;-strafe"
alias +sr50r_2key "+right\;+moveright\;+strafe"
alias -sr50r_2key "-right\;-moveright\;-strafe"
bind Q +sr50l_2key
bind E +sr50r_2key

One Key
Usage: The player holds down E to SR-50 to the right and Q to SR-50 to the left. While moving backwards, the player holds Z to SR-50 to the back and left, and holds C to SR-50 to the back and right.

Code: [Select]
alias +sr50fl_1key "+forward\;+moveleft\;+left\;+strafe"
alias -sr50fl_1key "-forward\;-moveleft\;-left\;-strafe"
alias +sr50bl_1key "+back\;+moveleft\;+left\;+strafe"
alias -sr50bl_1key "-back\;-moveleft\;-left\;-strafe"
alias +sr50fr_1key "+forward\;+moveright\;+right\;+strafe"
alias -sr50fr_1key "-forward\;-moveright\;-right\;-strafe"
alias +sr50br_1key "+back\;+moveright\;+right\;+strafe"
alias -sr50br_1key "-back\;-moveright\;-right\;-strafe"
bind Q +sr50fl_1key
bind E +sr50fr_1key
bind Z +sr50bl_1key
bind C +sr50br_1key

Turnspeeds Toggle
Usage: The player will SR-40 to the right with W & D and then SR-50 by holding down the second mouse button. Note that this method will require the player to press the second mouse button when first spawning to initialize the controls. If the player forgets do do this, the A and the D keys will spin the player's view instead of moving them to the left or right. Note that +sr50l_ts will take the place of the key bound to +moveleft and +sr50r_ts will take the place of the key bound to +moveright.

Code: [Select]
alias +sr50l_ts "+left\;+moveleft"
alias -sr50l_ts "-left\;-moveleft"
alias +sr50r_ts "+right\;+moveright"
alias -sr50r_ts "-right\;-moveright"
alias +sr50_ts_toggle "turnspeeds 65536\;+strafe"
alias -sr50_ts_toggle "turnspeeds 0\;-strafe"
bind A +sr50l_ts
bind D +sr50r_ts
bind mouse2 +sr50_ts_toggle


Developer's Corner / Ticcmd queue discussion

« on: September 04, 2012, 15:53:41 »
A ticcmd is a collection of data that represents the action buttons a player presses during a particular gametic (1/35 second frame). This includes the amount of movement in the forward/backwards direction, the amount of movement in the left/right direction, status of the +use, +jump, and +attack buttons, and the desired view angle and view pitch.

The ticcmd queue was introduced in Odamex 0.5.6 as a means to smooth the stream of ticcmds going from clients to the server so that the server can process one ticcmd every gametic on average and keep players moving smoothly regardless of sudden spikes in network latency (also called network jitter). At the start of a gametic, the server will enqueue incoming ticcmds for each player and then process the first ticcmd in the queue. If there is a latency spike, the player will typically have a period where the server doesn't receive any ticcmds from the player and then will subsequently receive several ticcmds at once. The means the player's ticcmd queue will be shrinking (or empty) for a few gametics and then will suddenly grow with several ticcmds.

When a player has a latency spike, they are often left with a ticcmd queue with several ticcmds. This creates additional latency between when the player sends the server the ticcmd and when the server processes it. Additional latency is undesirable and Odamex attempts to reduce this latency in a couple manners.

The server will process all of the ticcmds in a player's ticcmd queue when the player is dead, since the dead player does not require smooth movement. Additionally, if a player is not visible to any other players, the server will process 2 ticcmds once every 0.5 seconds as well as if the player is standing still.

Although these methods allows the player reduce the size of their ticcmd queue, it is far from ideal. Odamex may need other ways to reduce the queue size. I hope to gather data regarding ticcmd queue size during gameplay for informational purposes.


Technical Support / ZDoom-derived Ports & Mouse Information

« on: December 09, 2011, 12:06:33 »
After thorough investigation, I have discovered a great deal about the internals of how ZDoom 1.23 and its derivatives handle mouse input which I will try to distill here.  This post will be updated as more information is discovered.

Odamex's Mouse Input Types

Odamex uses DirectInput for its mouse input on the Windows platform and as of 0.5.6, it provides two mouse types: Doom and Odamex.  The input processing for the two types is identical and the only difference is with regard to the mouse_sensitivity cvar, where the mouse_sensitivity value with the Doom mouse type is always 5 less than the equivalent mouse_sensitivity value for the Odamex mouse type.

For example, Doom mouse type & mouse_sensitivity = 35 is equivalent to Odamex mouse type & mouse_sensitivity = 40.

ZDoom's Mouse Input Types

The most important factor relating to mouse input in ZDoom-derived ports is the cvar in_mouse.  With the default value of in_mouse = 0, the game selects the default method of mouse input for the OS, which is using DirectInput (also can be explicitly specified with in_mouse = 2). A value of in_mouse = 1 uses USER32.DLL calls (we'll call this Win32).  The overwhelming majority of players will have in_mouse set to 0 and therefore use the DirectInput mouse type.

ZDoom DirectInput Mouse

DirectInput (part of the DirectX library) retrieves "raw" mouse input values, unscaled by the OS.  This bypasses the Windows mouse sensitivity and acceleration settings.  When ZDoom uses this mouse type, it scales the mouse movement values along the x-axis by a factor of 4.0 and does not change the movement values along the y-axis.  

Users of this mouse type can easily convert their ZDoom mouse settings to Odamex's Doom mouse type using the following equations:
Doom mouse_sensitivity = (ZDoom mouse_sensitivity * 40) - 5
Doom m_pitch = (ZDoom m_pitch / 4)

So using the default ZDoom mouse_sensitivity = 1.0, a user should choose mouse_sensitivity = 35 when using the Doom mouse type in Odamex.  Using the default ZDoom m_pitch = 1.0, a user should choose m_pitch = 0.25 with the Doom mouse type in Odamex.  Since ZDoom does not offer mouse acceleration, players wanting the same feel in Odamex should set mouse_acceleration to 0.

ZDoom Win32 Mouse
The Win32 mouse type gets mouse values from the Windows OS like a normal desktop application.  Windows first applies its sensitivity scaling to the user's mouse input and then applies its acceleration curve if the user has not disabled it in the Windows Control Panel.  Finally, Windows passes the scaled mouse values to the game.

Windows uses a non-linear table to determine how its Control Panel sensitivity setting will scale the mouse input.  Players can scale their Zdoom mouse_sensitivity setting by the following table to match their Windows mouse sensitivity setting.

Windows Sensitivity Factors (when acceleration is disabled)
  • 1  0.03125
  • 2  0.0625
  • 3  0.25
  • 4  0.5
  • 5  0.75
  • 6  1.0
  • 7  1.5
  • 8  2.0
  • 9  2.5
  • 10 3.0
  • 11 3.5

If a player has not disabled acceleration (sometimes also called Enhanced Pointer Precision) in the Windows Control Panel, they also are subjected to Windows mouse acceleration as well as an different set of sensitivity scaling factors, as seen below.

Windows Sensitivity Factors (with acceleration enabled)
  • 1  0.1
  • 2  0.2
  • 3  0.4
  • 4  0.6
  • 5  0.8
  • 6  1.0
  • 7  1.2
  • 8  1.4
  • 9  1.6
  • 10 1.8
  • 11 2.0

Describing how the mouse pointer algorithm works is beyond the scope of this posting, however, my testing confirms that this reference ( appears to give a very accurate description of the algorithm used in Windows XP and Vista/7.

Finally, when ZDoom uses the Win32 mouse type, it scales the mouse movement values along the x-axis by a factor of 3.0 and scales movement along the y-axis by a factor of 2.0.

The below equations will allow most players to easily convert their mouse to the Doom mouse type in Odamex.  Note that the Windows Sensitivity Factor is given in the above table.

Doom mouse_sensitivity = (30 * (ZDoom mouse_sensitivity) * (Windows Sensitivity Factor)) - 5
Doom m_pitch = 0.5 * (ZDoom m_pitch) * (Windows Sensitivity Factor)
mouse_acceleration = 0 or 2.6 (depending on whether it's enabled in Windows Control Panel)
mouse_threshold = 6

Given a player who uses the default mouse_sensitivity = 1.0 and m_pitch = 1.0 in their ZDoom-derived port and uses the default mouse settings in the Windows Control Panel of sensitivity = 6 and acceleration turned on, they should use the following settings:
mouse_type = 0 (Doom mouse type)
mouse_sensitivity = 25
m_pitch = 0.5
mouse_acceleration = 2.6
mouse_threshold = 6

Pages: [1]