1 (Presented with permission from original author)
MobilityWare (formerly Alion Science and Technology)
Your team’s producer decides that it’s time to release a networked game, saying “We can publish across
a network, right?” Bob kicks off a few internet searches and replies, “Doesn’t look that hard.” He dives
into the code, and before long, Bob is ready to begin testing. Then, he stares in bewilderment as the
characters jerk and warp across the screen and the vehicles hop, bounce, and sink into the ground. Thus
begins the nightmare that will be the next few months of Bob’s life as he attempts to implement dead
reckoning “just one more tweak” at a time.
This gem describes everything needed to add believable, stable, and efficient dead reckoning to a
networked game. It covers the fundamental theory, compares algorithms, and makes a case for a new
technique. It explains what’s tricky about dead reckoning, addresses common myths, and provides a
clear implementation path. The topics are demonstrated with a working networked game that includes
source. This gem will help you avoid countless struggles and dead ends so that you don’t end up like
Bob isn’t a bad developer; he just made some reasonable, but misguided, assumptions. After all, the
basic concept is pretty straight forward. Dead reckoning (DR) is the process of predicting where an
actor is right now by using its last known position, velocity, and acceleration. It applies to almost any
type of moving actor, including cars, missiles, monsters, helicopters, and characters on foot. For each
remote actor being controlled somewhere else on the network, we receive updates about its kinematic
state that include position, velocity, acceleration, orientation, and angular velocity. In the simplest
implementation, we take the last position we received on the network and project it forward in time.
Then, on the next update, do some sort of blending and start the process all over again. Bob is right that
the fundamentals aren’t that complex, but making it believable is a different story.
Let’s start with the following fact: there is no such thing as ground truth in a networked environment.
Ground truth implies that you have perfect knowledge of the state of all actors at all times. Surely, you
can’t know the exact state of all remote actors without sending updates every frame in a zero packet
loss, zero latency environment. What you have instead is your own perceived truth. Thus, the goal
becomes believable estimation, as opposed to perfect re-creation.
To derive the math, we start with the simplest case: a new actor comes across the network. In this case,
one of our opponents is driving a tank, and we received our first kinematic state update as it came into
view. From here, dead reckoning is a straightforward linear physics problem as described by Aronson
. Using the values from the message, we put the vehicle at position
, and begin moving it at
as shown in Figure 1.1. The dead reckoned position at a specific time,
Qt, is calculated with the following equation:
Figure 1.1. The first update is simple.
Continuing our scenario, the opponent saw us, slowed his tank, and took a hard right. Soon, we
receive a message updating his kinematic state. At this point, we have conflicting realities. The first
reality is where we guessed he would be
using the previous formula. The second reality is where he
actually went, our new
, which we refer to as the last known state because it’s the last thing we know
to be correct. This dual state is the beginning of Bob’s nightmares. Since there are two versions of each
value, we use the prime notation (e.x.
) to indicate last known as shown in Figure 1.2.
Figure 1.2. The next update creates two realities (red – estimate, green – actual).
Chapter 1 Believable Dead Reckoning for Networked Games 3
To resolve the two realities, we need to create a believable curve between where we thought the
tank would be, and where we estimate it will be in the future. Don’t bother to path the remote tank
through its last known position,
. Instead, just move it from where it is now,
, to where we think it
is supposed to be in the future,
The human brain is amazing at recognizing patterns [Koster 2005] and more importantly, changes in
patterns, such as when the tiniest piece of fuzz moves past our peripheral vision. What this means is
that players will notice subtle discontinuities in a vehicle path long before they realize the vehicle is in
the wrong location. Therefore, discontinuities such as hops, warps, wobbles, and shimmies are the
If you crack open any good 3D math textbook, you’ll find a variety of algorithms for defining a curve.
Fortunately, we can discard most of them right away because they are too CPU intensive or are not
appropriate (e.g., B-splines do not pass through the control points). For dead reckoning, we have the
additional requirement that the algorithm must work well for a single segment of a curve passing
through two points: our current location
and the estimated future location
. Given all these
requirements, we can narrow the selection down to a few types of curves: cubic Bézier splines, Catmull-
Rom splines, and Hermite curves [Lengyel 2004, Van Verth and Bishop 2008].
These curves perform pretty well and follow smooth, continuous paths. However, they also tend to
create minor repetitive oscillations. The oscillations are relatively small, but noticeable, especially
when the actor is making a lot of changes (e.g., moving in a circle). In addition, the oscillations tend to
become worse when running at inconsistent frame rates or when network updates don’t come at regular
intervals. In short, they are too wiggly.
Let’s try a different approach. Our basic problem is that we need to resolve two realities (the current
and the last known
). Instead of creating a spline segment, let’s try a straightforward blend. We create
two projections, one with the current and one with the last known kinematic state. Then, we simply
blend the two together using a standard linear interpolation (lerp). The first attempt looks like this:
(Projecting from where we were)
(Projecting from last known)
, the dead reckoned location at a specified time. Time values such as
explained in Section 1.4. Note that both projection equations above use the last known value of
. In theory, the current projection Pt should use the previous acceleration
continuity. However, in practice,
converges to the true path much quicker and reduces oscillation.
This technique actually works pretty well. It is simple and gives a nice curve between our points.
Unfortunately, it has oscillations that are as bad as or worse than the spline techniques. Upon inspection,
it turns out that with all of these techniques, the oscillations are caused by the changes in velocity (
). Maybe if we do something with the velocity, we can reduce the oscillations. So, let’s try it
again, with a tweak. This time, we compute a linear interpolation between the old velocity
last known velocity
to create a new blended velocity
. Then, we use this to project forward from
where we were.
The technique, projective velocity blending, works like this:
(Projecting from where we were)
(Projecting from last known)
And the red lines in Figure 1.3 show what it looks like in action.
Figure 1.3. Dead reckoning with projective velocity blending (shown in red)
In practice, this works out magnificently! The blended velocity and change of acceleration
significantly reduces the oscillations. In addition, this technique is the most forgiving of both
inconsistent network update rates and changes in frame rates.
Chapter 1 Believable Dead Reckoning for Networked Games 5
So it sounds good in theory, but let’s get some proof. We can perform a basic test by driving a vehicle
in a repeatable pattern (e.x., a circle). By subtracting the real location from the dead reckoned location,
we can determine the error. The images in Figure 1.4 and statistics in Table 1.1 show the clear result.
The projective velocity blending is roughly 5–7% more accurate than cubic Bézier splines. That ratio
improves a bit more when you can’t publish acceleration. If you want to test it yourself, the demo
application on the DVD has implementations of both projective velocity blending and cubic Bézier
Figure 1.4. Cubic Bézier splines (left) vs. projective velocity blending (right), with acceleration (top) and without
Table 1.1. Improvement using projective velocity blending.
As a final note, if you decide to implement a spline behavior instead of projective velocity blending,
you might consider the cubic Bézier splines [Van Verth and Bishop 2008]. They are slightly easier to
implement because the control points can simply be derived from the velocities
. The source
on the DVD includes a full implementation.
So far, we’ve glossed over time. That’s okay for an introduction, but, once you begin coding, the
concept of time gets twisted up in knots. So, let’s talk about T.
The goal is to construct a smooth path that an actor can follow between two moments in time
. These two times mark the exact beginning and end of the curve and are defined by locations
, respectively. The third time
is how much time has elapsed since
. The final time
far the actor has traveled along the path as a normalized value with
is easy. It’s the time stamp when the last known values were updated. Basically, it’s “now” at
the time of the update. If you’ve seen the movie Spaceballs, then
is “now, now”. When we process
a new network update, we mark
as now and set
back to 0.0. The slate is wiped clean, and we start
a whole new curve, regardless of where we were.
is now, then
must be in the future. But, how far into the future,
, should the projection go?
Well, if we knew that the actor updates were coming at regular intervals, then we could just use the
inverse update rate. So, for three updates per second,
. Even though network updates won’t
always be perfectly spaced out, it still gives a stable and consistent behavior. Naturally, the update rate
varies significantly depending on the type of game, the network conditions, and the expected actor
behavior. As a general rule of thumb, an update rate of three per second looks decent and five or more
per second looks great.
Chapter 1 Believable Dead Reckoning for Networked Games 7
From an implementation perspective, normalized time values from 0 to 1 aren’t terribly useful. In many
engines, you typically get a time since last frame,
. We can easily add this up each frame to give the
total time since the last update
. Once we know
, we can compute our normalized time
Now we have all the times we need to compute the projective velocity blending equations. That
leaves just one final wrinkle in time. It happens when we go past
). This is a very common
case that can happen if we miss an update, have any bit of latency, or even have minor changes in frame
rate. From earlier,
is clamped at 1.0, the
t drops out, leaving the original equation:
The math simplifies quite nicely and continues to work for any value of
Here are a few tips to consider:
■ Due to the nature of networking, you can receive updates at any time, early or late. In order to
continuity, you need to calculate the instantaneous velocity between this frame’s and
last frame’s dead reckoned position,
. When you get the next update and start the new
curve, use this instantaneous velocity for
. Without this, you will see noticeable changes in
velocity at each update.
■ Actors send updates at different times based on many factors, including creation time, behavior,
server throttling, latency, and whether they are moving. Therefore, track the various times
separately for each actor (local and remote).
■ If pre-deciding your publish rate is problematic, you could calculate a run-time average of how
often you have been receiving network updates and use that for
. This works okay, but is less
stable than a predetermined rate.
■ In general, the location and orientation get updated at the same time. However, if they are published
separately, you’ll need separate time variables for each.
■ It is possible to receive multiple updates in a single frame. In practice, let the last update win. For
performance reasons, perform the dead reckoning calculations later in the game loop, after the
network messages are processed. Ideally, you will run all the dead reckoning in a single component
that can split the work across multiple worker threads.
■ For most games, it is not necessary to use timestamps to sync the clocks between clients/servers in
order to achieve believable dead reckoning.
So far, the focus has been on handling network updates for remote actors. However, as with most things,
garbage-in means garbage-out. Therefore, we need take a look at the publishing side of things. In this
section, forget about the actors coming in over the network, and focus on the locally controlled actors.
Let’s go back and consider the original tank scenario from the opponent’s perspective. The tank is now
a local actor and is responsible for publishing updates on the network. Since network bandwidth is a
precious resource, we should reduce traffic if possible. So the first optimization is to decide when we
need to publish. Naturally, there are times when players are making frequent changes in direction and
speed and five or more updates per second are necessary. However, there are many more times when
the player’s path is stable and easy to predict. For instance, the tank might be lazily patrolling, might
be heading back from a respawn, or even sitting still (e.g., the player is chatting).
The first optimization is to only publish when necessary. Earlier, we learned that it is better to have
a constant publish rate (e.g., three per second) because it keeps the remote dead reckoning smooth.
However, before blindly publishing every time it’s allowed (e.g., every 0.333 s), we first check to see
if it’s necessary. To figure that out, we perform the dead reckoning as if the vehicle was remote. Then,
we compare the real and the dead reckoned states. If they differ by a set threshold, then we go ahead
and publish. If the real position is still really close to the dead reckoned position, then we hold off.
Since the dead reckoning algorithm on the remote side already handles
, it’ll be fine if we don’t
update right away. This simple check, shown in Listing 1.1, can significantly reduce network traffic.
Listing 1.1. Publish – Is Update Necessary?
bool ShouldForceUpdate(const Vec3& pos, const Vec3& rot)
bool forceUpdateResult = false;
Vec3 posMoved = pos – mCurDeadReckoned_Pos;
Vec3 rotTurned = rot – mCurDeadReckoned_Rot;
if ((posMoved.length2() > mPosThreshold2) ||
(rotTurned.length2() > mRotThreshold2))
// Rot.length2 is a fast approx (i.e., not a quaternion)
forceUpdateResult = true;
Chapter 1 Believable Dead Reckoning for Networked Games 9
// ... can use other checks such as velocity and accel
Clearly, we need to publish each actor’s kinematic state, which includes the position, velocity,
acceleration, orientation, and angular velocity. But, there are a few things to consider. The first, and
least obvious, is the need to separate the actor’s real location and orientation from its last known
location and orientation. Hopefully, your engine has an actor property system [Campbell 2006] that
enables you to control which properties get published. If so, you need to be absolutely sure you never
publish (or receive) the actual properties used to render location and orientation. If you do, the remote
actors will get an update and render the last known values instead of the results of dead reckoning. It’s
an easy thing to overlook and results in a massive one-frame discontinuity (a.k.a. blip). Instead, create
publishable properties for the last known values (i.e., location, velocity, acceleration, orientation, and
angular velocity) that are distinct from the real values.
The second consideration is partial actor updates, messages that only contains a few actor
properties. To obtain believable dead reckoning, the values in the kinematic state need to be published
frequently. However, the rest of the actor’s properties usually don’t change that much, so the publishing
code needs a way to swap between a partial and full update. Most of the time, we just send the kinematic
properties. Then, as needed, we send other properties that have changed and periodically (e.g., every
10 s) send out a heartbeat that contains everything. The heartbeat can help keep servers and clients in
In the quest to create believable dead reckoning, acceleration can be a huge advantage, but be warned
that some physics engines give inconsistent (a.k.a. spiky) readings for linear acceleration, especially
when looked at in a single frame as an instantaneous value. Because acceleration is difficult to predict
and is based on the square of time, it can sometimes make things worse by introducing noticeable under-
and over-compensations. For example, this can be a problem with highly jointed vehicles for which the
forces are competing on a frame-by-frame basis or with actors that intentionally bounce or vibrate.
With this in mind, the third consideration is determining what the last known values should be. The
last known location and orientation come directly from the actor’s current render values. However, if
the velocity and acceleration values from the physics engine are giving poor results, consider
calculating an instantaneous velocity and acceleration instead. These instantaneous values are
calculated locally, before publishing, but are similar to what happens in the dead reckoning (
). In extreme cases, consider blending the instantaneous velocity over two or three frames
to average out some of the sharp changes.
Below are some final tips for publishing:
■ Published values can be quantized or compressed to reduce bandwidth [Sayood 2006].
■ If an actor isn’t stable at speeds near zero due to physics, consider publishing a zero velocity and/or
acceleration instead. The projective velocity blend will resolve the small translation change
■ If publishing regular heartbeats, be sure to sync them with the partial updates to keep the updates
regular. Also, try staggering the heartbeat time by a random amount to prevent clumps of full
updates caused by map loading.
■ Some types of actors don’t really move (e.g., a building or static light). Improve performance by
using a static mode that simply teleports actors.
■ In some games, the orientation might matter more than the location, or vice versa. Consider
publishing them separately and at different rates.
■ To reduce the bandwidth using ShouldForceUpdate(), you need to dead reckon the local actors
in order to check against the threshold values.
■ Evaluate the order of operations in the game loop to ensure published values are computed
correctly. An example order might include: handle user input, tick local (process incoming
messages and actor behaviors), tick remote (perform dead reckoning), publish DR, start physics
(background for next frame), update cameras, render, finish physics. A bad order will cause all
sorts of hard to debug dead reckoning anomalies.
■ There is an optional damping technique that can help reduce oscillations when the acceleration is
changing rapidly (e.g., zigzagging). Take the current and previous acceleration vectors and
normalize them. Then, compute the dot product between them and treat it as a scalar to reduce the
acceleration before publishing (shown in ComputeCurrentVelocity in Listing 1.2).
■ Acceleration in the up/down direction can sometimes cause floating or sinking. Consider publishing
a zero instead.
When all the pieces are put together, the code looks like Listing 1.2:
Listing 1.2. Publish - The Whole Story
void OnTickRemote(const TickMessage& tickMessage)
// This is for local actors, but happens during Tick Remote.
double elapsedTime = tickMessage.GetDeltaSimTime();
bool forceUpdate = false, fullUpdate = false;
Vec3 rot = GetRotation();
Vec3 pos = GetTranslation();
mSecsSinceLastUpdateSent += elapsedTime;
Chapter 1 Believable Dead Reckoning for Networked Games 11
mTimeUntilHeartBeat -= elapsedTime;
// Have to update instant velocity even if we don’t publish
ComputeCurrentVelocity(elapsedTime, pos, rot);
if ((mTimeUntilHeartBeat <= 0.0F) || (IsFullUpdateNeeded()))
fullUpdate = true;
forceUpdate = true;
forceUpdate = ShouldForceUpdate(pos, rot);
fullUpdate = (mTimeUntilHeartBeat < HEARTBEAT_TIME * 0.1F);
mTimeUntilHeartBeat = HEARTBEAT_TIME; // +/- random offset
mSecsSinceLastUpdateSent = 0.0F;
void SetLastKnownValuesBeforePublish(const Vec3& pos, const Vec3& rot)
// (OPTIONAL!) ACCELERATION dampen to prevent wild swings.
// Normalize current accel. Dot with accel from last update. Use
// the product to scale our current Acceleration.
Vec3 curAccel = GetCurrentAccel();
float accelScale = curAccel * mAccelOfLastPublish;
mAccelOfLastPublish = curAccel; // (pre-normalized)
SetLastKnownAccel(GetCurrentAccel() * Max(0.0F, accelScale));
void ComputeCurrentVelocity(float deltaTime,
const Vec3& pos, const Vec3& rot)
if ((mPrevFrameTime > 0.0F) && (mLastPos.length2() > 0.0F))
Vec3 prevComputedLinearVel = mComputedLinearVel;
Vec3 distanceMoved = pos - mLastPos;
mComputedLinearVel = distanceMoved / mPrevFrameTime;
// accel = the instantaneous differential of the velocity
Vec3 deltaVel = mComputedLinearVel - prevComputedLinearVel;
Vec3 computedAccel = deltaVel / mPrevDeltaFrameTime;
computedAccel.z() = 0.0F; // up/down accel isn’t always helpful
mLastPos = pos;
mPrevFrameTime = deltaTime;
Chapter 1 Believable Dead Reckoning for Networked Games 13
No matter how awesome your dead reckoning algorithm becomes, at some point, the problem of ground
clamping is going to come up. The easiest way to visualize the problem is to drop a vehicle off of a
ledge. When it impacts the ground, the velocity is going to project the dead reckoned position under
the ground. Few things are as disconcerting as watching a tank disappear halfway into the dirt. As an
example, the demo allows mines to fall under ground.
As with many dead reckoning problems, there isn’t one perfect solution. However, some simple ground
clamping can make a big difference, especially for far away actors. Ground clamping is adjusting an
actor’s vertical position and orientation to make it follow the ground. The most important thing to
remember about ground clamping is that it happens after the rest of the dead reckoning. Do everything
The following is one example ground clamping technique. Using the final dead reckoned position
and orientation, pick three points on the bounding surface of the actor. Perform a ray cast starting above
those points and directed downward. Then, for each point, check for hits and clamp the final point if
appropriate. Compute the average height H of the final points
, and compute the normal
N of the triangle through those points as follows:
( ) ( )
( ) ( )
Use H as the final clamped ground height for the actor and use the normal to determine the final
orientation. While not appropriate for all cases, this technique is fast and easy to implement, making it
ideal for distant objects.
■ Another possible solution for this problem is to use the physics engine to prevent interpenetration.
This has the benefit of avoiding surface penetration in all directions, but it can impact performance.
It can also create new problems such as warping the position, the need for additional blends, and
■ Another way to minimize ground penetration is to have local actors project their velocity and
acceleration into the future before publishing. Then, damp the values as needed so that penetration
won’t occur on remote actors (a method known as predictive prevention). This simple trick can
improve behavior in all directions and may eliminate the need to check for interpenetration.
■ When working with lots of actors, consider adjusting the ground clamping based on distance to
improve performance. You can replace the three point ray multi-cast, with a single point and adjust
the height directly using the intersection normal for orientation. Further, you can clamp
intermittently and use the offset from prior ground clamps.
■ For character models, it is probably sufficient to use single-point ground clamping. Single-point
clamping is faster, and you don’t need to adjust the orientation.
■ Consider supporting several ground clamp modes. For flying or underwater actors, there should be
a “no clamping” mode. For vehicles that can jump, consider an “only clamp up” mode. The last
mode, “always clamp to ground”, would force the clamp both up and down.
Orientation is a critical part of dead reckoning. Fortunately, the basics of orientation are similar to what
was discussed for position. We still have two realities to resolve: the current drawn orientation and the
last known orientation we just received. And, instead of velocity, there is angular velocity. But that’s
where the similarities end.
Your engine might use HPR (heading, pitch, roll), XYZ vectors, or full rotation matrices to define an
orientation. However, when it comes to dead reckoning, you’ll be rotating and blending angles in three
dimensions, and there is simply no getting around quaternions [Hanson 2006]. Fortunately, quaternions
are easier to implement than they are to understand [Van Verth and Bishop 2008]. So, if your engine
doesn’t support them, do yourself a favor and code up a quaternion class. Make sure it has the ability
to create a quaternion from an axis/angle pair and can perform spherical linear interpolations (slerp). A
basic implementation of quaternions is provided with the demo code on the DVD.
Hypothetically, orientation should have the same problems that location had. In reality, actors
generally turn in simpler patterns than they move. Some actors turn slowly (e.g., cars) and others turn
extremely quickly (e.g., characters). Either way, the turns are fairly simplistic, and oscillations are
rarely a problem. This means
continuity is less important and explains why many engines
don’t bother with angular acceleration.
With this in mind, dead reckoning the orientation becomes pretty simple: project both realities, and
then blend between them. To project the orientation, we need to calculate the rotational change from
the angular velocity. Angular velocity is just like linear velocity; it is the amount of change per unit
time and is usually represented as an axis of rotation whose magnitude corresponds to the rate of
rotation about that axis. It typically comes from the physics engine, but it can be calculated by dividing
the change in orientation by time. In either case, once you have the angular velocity vector, the
is computed as shown in Listing 1.3:
Listing 1.3. Computing Rotational Change
// normalize() returns length.
float angVelMagnitude = angVelAxis.normalize();
// Rotation around the axis is magnitude of ang vel * time.
float rotationAngle = angVelMagnitude * actualRotationTime;
Quat rotationFromAngVel(rotationAngle, angVelAxis);
Chapter 1 Believable Dead Reckoning for Networked Games 15
If you also have angular acceleration, just add it to rotationAngle. Next, compute the two
projections and blend using a spherical linear interpolation. Use the last known angular velocity in both
projections, just like the last known acceleration was used for both equations in the projective velocity
(Impact of angular velocity)
(Rotated from where we were)
(Rotated from last known)
slerp , ,
This holds true for
. Once again,
is clamped at 1.0, so the math simplifies when
. (Rotated from last known)
This technique may not be sufficient for some types of actors. For example, the orientation of a car and
its direction of movement are directly linked. Unfortunately, the dead reckoned version is just an
approximation with two sources of error. The first is that the orientation is obviously a blended
approximation that will be behind and slightly off. But, even if you had a perfect orientation, the remote
vehicle is following a dead reckoned path that is already an approximation. Hopefully, you can publish
fast enough that neither of these become a problem. If not, you may need some custom actor logic that
can reverse engineer the orientation from the dead reckoned values; that is, estimate an orientation that
would make sense given the dead reckoned velocity. Another possible trick is to publish multiple points
along your vehicle (e.g., one at front and one in back). Then, dead reckon the points, and use them to
orient the vehicle (e.g., bind the points to a joint).
This last section introduces a variety of advanced topics that impact dead reckoning. The details of
these topics are generally outside the scope of this gem, but, in each case, there are specific
considerations that are relevant to dead reckoning.
Some engines use physics for both the local and the remote objects. The idea is to improve believability
by re-creating the physics for remote actors, either as a replacement for or in addition to the dead
reckoning. There are even a few techniques that take this a step further by allowing clients to take
ownership of actors so that the remote actors become local actors, and vice versa [Feidler 2009]. In
either of these cases, combining physics with dead reckoning gets pretty complex. However, the take
away is that even with great physics, you’ll end up with cases where the two kinematic states don’t
perfectly match. At that point, use the techniques in this gem to resolve the two realities.
Dead reckoning can be very useful for server validation of client behavior. The server should always
maintain a dead reckoned state for each player or actor. With each update from the clients, the server
can use the previous last known state, the current last known state, and the ongoing results of dead
reckoning as input for its validation check. Compare those values against the actor’s expected behavior
to help identify cheaters.
Imagine player A (local) shoots a pistol at player B (remote, slow update). If implemented poorly, player
A has to “lead” the shot ahead or behind player B based on the ping time to the server. A good dead
reckoning algorithm can really help here. As an example, client A can use the current dead reckoned
location to determine that player B was hit and then send a hit request over to the server. In turn, the
server can use the dead reckoned information for both players, along with ping times, to validate that
client A’s hit request is valid from client A’s perspective. This technique can be combined with server
validation to prevent abuse. For player A, the game feels responsive, seems dependent on skill, and
plays well regardless of server lag.
Complex actors often have articulations, which are attached objects that have their own independent
range of motion and rotation. Articulations can generally be lumped into one of two groups: real or
fake. Real articulations are objects whose state has significant meaning, such as the turret that’s pointing
directly at you! For real articulations, use the same techniques as if it were a full actor. Fortunately,
many articulations such as turrets, can only rotate, which removes the overhead of positional blending
and ground clamping. Fake articulations are things like tires and steering wheels where the state is
either less precise or changes to match the dead reckoned state. For those, you may need to implement
custom behaviors, such as for turning the front tires to approximate the velocity calculated by the dead
Some actors just need to follow a specified path, such as a road, a predefined route, or the results of an
AI plan. In essence, this is not much different from the techniques described above. Except, instead of
curving between two points, the actor is moving between the beginning and end of a specified path. If
the client knows how to recreate the path, then the actor just needs to publish how far along the path it
, as well as how fast time is changing,
. When applicable, this technique can significantly reduce
bandwidth. Moyer and Speicher  have a detailed exploration of this topic.
The first myth this gem addresses is that there is no ground truth. However, one technique, delayed
dead reckoning, can nearly recreate it, albeit by working in the past. With delayed dead reckoning, the
client buffers network updates until it has enough future data to recreate a path. This eliminates the
need to project into the future because the future has already arrived. It simplifies to a basic curve
Chapter 1 Believable Dead Reckoning for Networked Games 17
problem. The upside is that actors can almost perfectly recreate the original path. The obvious downside
is that everything is late, making it a poor choice for most real-time actors. This technique can be useful
when interactive response time is not the critical factor, such as with distant objects (e.g., missiles),
slow moving system actors (e.g., merchant NPCs), or when playing back a recording. Note that delayed
dead reckoning can also be useful for articulations.
Online games that support thousands of actors sometimes use a subscription zoning technique to reduce
rendering time, network traffic, and CPU load [Cado 2007]. Zoning is quite complex, but has several
impacts on dead reckoning. One significant difference is the addition of dead reckoning modes that
swap between simpler or more complex dead reckoning algorithms. Actors that are far away or
unimportant can use a low-priority mode with infrequent updates, minimized ground clamping,
quantized data, or simpler math and may take advantage of delayed dead reckoning. The high-priority
actors are the only ones doing frequent updates, articulations, and projective velocity blending. Clients
are still responsible for publishing normally, but the server needs to be aware of which clients are
receiving what information for which modes and publish data accordingly.
Dead reckoning becomes a major consideration the moment your game becomes networked.
Unfortunately, there is no one-size fits all technique. The gaming industry is incredibly diverse and the
needs of a first-person MMO, a top-down RPG, and a high-speed racing game are all different. Even
within a single game, different types of actors might require different techniques.
The underlying concepts described in this gem should provide a solid foundation for adding dead
reckoning to your own game regardless of the genre. Even so, dead reckoning is full of traps and can
be difficult to debug. Errors can occur anywhere, including the basic math, the publishing process, the
data sent over the network, or the plain old latency, lag, and packet issues. Many times, there are
multiple problems going on at once and they can come from unexpected places, such as bad values
coming from the physics engine or uninitialized variables. When you get stuck, refer back to the tips in
each section and avoid making assumptions about what is and is not working. Believable dead
reckoning is tricky to achieve, but the techniques in this gem will help make the process as easy as it
Special thanks to David Guthrie for all of his contributions.
[Aronson 1997] Aronson, Jesse. “Dead Reckoning: Latency Hiding for Networked Games”.
Gamasutra, September 19, 1997. Online at http://
[Cado 2007] Cado, Olivier. “Propagation of Visual Entity Properties Under Bandwidth Constraints”.
Gamasutra, May 24, 2007. Online at http://www.
[Campbell 2006] Campbell, Matt and Murphy, Curtiss, “Exposing Actor Properties Using
Nonintrusive Proxies”. Game Programming Gems 6. Charles River Media, 2006.
[Feidler 2009] Fiedler, Glenn. “Drop in COOP for Open World Games”. Game Developer’s
Conference, 2009. Online at http://gafferongames.wordpress. com/.
[Hanson 2006] Hanson, Andrew. Visualizing Quaternions. Morgan Kaufmann, 2006.
[Koster 2005] Koster, Raph. A Theory of Fun for Game Design. Paraglyph Press, 2005.
[Lengyel 2004] Lengyel, Eric. Mathematics for 3D Game Programming & Computer Graphics, 2nd
edition. Charles River Media, 2004.
[Moyer and Speicher 2005] Moyer, Dale and Speicher, Dan. “A Road-Based Algorithm for Dead
Reckoning”. Interservice/Industry Training, Simulation, and Education Conference, 2005.
[Sayood 2006] Sayood, Khalid. Introduction to Data Compression, 3rd edition. Morgan Kaufmann,
[Van Verth and Bishop 2008] Van Verth, James and Bishop, Lars. Essential Mathematics in Games
and Interactive Applications: A Programmer’s Guide, 2nd edition. Morgan Kaufmann, 2008.