ChapterPDF Available

Believable Dead Reckoning for Networked Games

Authors:
  • MobilityWare, Irvine, CA, United States

Abstract and Figures

Projective Velocity Blending Let’s try a different approach. Our basic problem is that we need to resolve two realities (the current P0 and the last known P’0). 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: This gives tQ, the dead-reckoned location at a specified time. (Time values such as Tt and T are explained in Section 18.4.) Note that both projection equations above use the last known value of acceleration A’0. In theory, the current projection tP should use the previous acceleration A0 to maintain C² continuity. However, in practice, A’0 converges to the true path much quicker and reduces oscillation.
Content may be subject to copyright.
1
1 (Presented with permission from original author)
Believable(Dead(Reckoning(
for(Networked(Games(
Curtiss Murphy
MobilityWare (formerly Alion Science and Technology)
1.1( Introduction(
Your teams producer decides that its time to release a networked game, saying We can publish across
a network, right?Bob kicks off a few internet searches and replies, Doesnt 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 Bobs life as he attempts to implement dead
reckoning just one more tweakat 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 whats 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 dont end up like
Bob.
1.2( Fundamentals(
Bob isnt 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 arent that complex, but making it believable is a different story.
Myth(BustingGround(Truth(
Lets 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
cant know the exact state of all remote actors without sending updates every frame in a zero packet
2
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.
Basic(Math(
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
[1997]. Using the values from the message, we put the vehicle at position
0
P¢
, and begin moving it at
velocity
0
V¢
with acceleration
0
A¢
as shown in Figure 1.1. The dead reckoned position at a specific time,
Qt, is calculated with the following equation:
2
00 0
1
2
t
QPVT AT
¢¢ ¢
=+ +
.
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
t
Q
using the previous formula. The second reality is where he
actually went, our new
0
P¢
, which we refer to as the last known state because its the last thing we know
to be correct. This dual state is the beginning of Bobs nightmares. Since there are two versions of each
value, we use the prime notation (e.x.
0
P¢
) 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. Dont bother to path the remote tank
through its last known position,
0
P¢
. Instead, just move it from where it is now,
0
P
, to where we think it
is supposed to be in the future,
1
P¢
.
Myth(BustingDiscontinuities(are(Not(Minor(
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
enemy.
1.3( Pick(an(Algorithm,(Any(Algorithm(
If you crack open any good 3D math textbook, youll 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
0
P
and the estimated future location
1
P¢
. Given all these
requirements, we can narrow the selection down to a few types of curves: cubic 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 dont come at regular
intervals. In short, they are too wiggly.
Projective(Velocity(Blending(
Lets try a different approach. Our basic problem is that we need to resolve two realities (the current
0
P
and the last known
0
P¢
). Instead of creating a spline segment, lets 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:
2
00 0
1
2
ttt
PPVT AT
¢
=+ +
(Projecting from where we were)
2
00 0
1
2
ttt
PPVT AT
¢¢¢ ¢
=+ +
(Projecting from last known)
( )
ˆ
tt tt
QP PPT
¢
=+ -
(Combined)
This gives
t
Q
, the dead reckoned location at a specified time. Time values such as
and
ˆ
T
are
explained in Section 1.4. Note that both projection equations above use the last known value of
4
acceleration
0
A¢
. In theory, the current projection Pt should use the previous acceleration
0
A
to maintain
2
C
continuity. However, in practice,
0
A¢
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 (
0
V
and
0
V¢
). Maybe if we do something with the velocity, we can reduce the oscillations. So, lets try it
again, with a tweak. This time, we compute a linear interpolation between the old velocity
0
V
and the
last known velocity
0
V¢
to create a new blended velocity
b
V
. Then, we use this to project forward from
where we were.
The technique, projective velocity blending, works like this:
( )
000
ˆ
b
VV VVT
¢
=+ -
(Velocity blending)
2
00
1
2
tbtt
PPVT AT
¢
=+ +
(Projecting from where we were)
2
00 0
1
2
ttt
PPVT AT
¢¢¢ ¢
=+ +
(Projecting from last known)
( )
ˆ
tt tt
QP PPT
¢
=+ -
. (Combined)
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
Prove(It!(
So it sounds good in theory, but lets 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 zier splines. That ratio
improves a bit more when you cant publish acceleration. If you want to test it yourself, the demo
application on the DVD has implementations of both projective velocity blending and cubic zier
splines.
Figure 1.4. Cubic Bézier splines (left) vs. projective velocity blending (right), with acceleration (top) and without
(bottom).
6
Table 1.1. Improvement using projective velocity blending.
Update rate
Cubic zier
(DR Error)
Projective velocity
(DR Error)
Improvement
1 Update/sec
1.5723 m
1.4584 m
7.24% closer
3 Updates/sec
0.1041 m
0.1112 m
6.38% closer
5 Updates/sec
0.0574 m
0.0542 m
5.57% closer
As a final note, if you decide to implement a spline behavior instead of projective velocity blending,
you might consider the cubic zier splines [Van Verth and Bishop 2008]. They are slightly easier to
implement because the control points can simply be derived from the velocities
0
V
and
0
V¢
. The source
on the DVD includes a full implementation.
1.4( Time(for(T(
So far, weve glossed over time. Thats okay for an introduction, but, once you begin coding, the
concept of time gets twisted up in knots. So, lets talk about T.
What(Time(is(It?(
The goal is to construct a smooth path that an actor can follow between two moments in time
0
T
and
. These two times mark the exact beginning and end of the curve and are defined by locations
0
P
and
1
P¢
, respectively. The third time
is how much time has elapsed since
0
T
. The final time
ˆ
T
represents how
far the actor has traveled along the path as a normalized value with
ˆ
0.0 1.0T££
.
0
T
is easy. Its the time stamp when the last known values were updated. Basically, its nowat
the time of the update. If youve seen the movie Spaceballs, then
0
T
is now, now. When we process
a new network update, we mark
0
T
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.
If
0
T
is now, then
must be in the future. But, how far into the future,
Δ
T
, 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,
Δ0.333 sT=
. Even though network updates wont
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
Time(to(Put(It(Together(
From an implementation perspective, normalized time values from 0 to 1 arent terribly useful. In many
engines, you typically get a time since last frame,
f
T
. 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
ˆ
T
as follows:
ttf
TTT¬+
Δ
ˆt
T
T
T
=
.
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
Δ
T
(i.e.,
Δt
TT>
). 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,
( )
ˆ
tt tt
QP PPT
¢
=+ -
.
Because
ˆ
T
is clamped at 1.0, the
P
t drops out, leaving the original equation:
2
00 0
1
2
ttt
QPVT AT
¢¢ ¢
=+ +
.
The math simplifies quite nicely and continues to work for any value of
ˆ
T
>= 1.0.
Just(in(Time(Notes(
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
maintain
1
C
continuity, you need to calculate the instantaneous velocity between this frame’s and
last frame’s dead reckoned position,
( )
1tt f
PP T
-
-
. When you get the next update and start the new
curve, use this instantaneous velocity for
0
V
. 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
Δ
T
. 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, youll 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.
8
For most games, it is not necessary to use timestamps to sync the clocks between clients/servers in
order to achieve believable dead reckoning.
1.5( Publish(or(Perish(
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.
When(To(Publish(
Lets go back and consider the original tank scenario from the opponents 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 players 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 its allowed (e.g., every 0.333 s), we first check to see
if its 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
Δt
TT>
, itll be fine if we dont
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;
if (enoughTimeHasPassed)
{
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
}
return (forceUpdateResult);
}
What(To(Publish(
Clearly, we need to publish each actors 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 actors 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. Its
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 actors properties usually dont 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
sync.
Myth(BustingAcceleration(Is(Not(Always(Your(Friend(
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 actors 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 (
( )
1tt f
PP T
-
-
). In extreme cases, consider blending the instantaneous velocity over two or three frames
to average out some of the sharp changes.
10
Publishing(Tips(
Below are some final tips for publishing:
Published values can be quantized or compressed to reduce bandwidth [Sayood 2006].
If an actor isnt 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
anyway.
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 dont 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.
The(Whole(Story(
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 dont publish
ComputeCurrentVelocity(elapsedTime, pos, rot);
if ((mTimeUntilHeartBeat <= 0.0F) || (IsFullUpdateNeeded()))
{
fullUpdate = true;
forceUpdate = true;
}
else
{
forceUpdate = ShouldForceUpdate(pos, rot);
fullUpdate = (mTimeUntilHeartBeat < HEARTBEAT_TIME * 0.1F);
}
if (forceUpdate)
{
SetLastKnownValuesBeforePublish(pos, rot);
if (fullUpdate)
{
mTimeUntilHeartBeat = HEARTBEAT_TIME; // +/- random offset
NotifyFullActorUpdate();
}
else
{
NotifyPartialActorUpdate();
}
mSecsSinceLastUpdateSent = 0.0F;
}
}
void SetLastKnownValuesBeforePublish(const Vec3& pos, const Vec3& rot)
{
SetLastKnownTranslation(pos);
SetLastKnownRotation(rot);
SetLastKnownVelocity(ClampTinyValues(GetCurrentVel()));
12
SetLastKnownAngularVel(ClampTinyValues(GetCurrentAngularVel()));
// (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();
curAccel.normalize();
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;
ClampTinyValues(mComputedLinearVel);
// accel = the instantaneous differential of the velocity
Vec3 deltaVel = mComputedLinearVel - prevComputedLinearVel;
Vec3 computedAccel = deltaVel / mPrevDeltaFrameTime;
computedAccel.z() = 0.0F; // up/down accel isnt always helpful
SetCurrentAcceleration(computedAccel);
SetCurrentVelocity(mComputedLinearVel);
}
mLastPos = pos;
mPrevFrameTime = deltaTime;
}
Chapter 1 Believable Dead Reckoning for Networked Games 13
1.6( Ground(Clamping(
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.
Can(We(Fix(It?(
As with many dead reckoning problems, there isnt one perfect solution. However, some simple ground
clamping can make a big difference, especially for far away actors. Ground clamping is adjusting an
actors 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
else first.
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
0
Q
,
1
Q
, and
2
Q
, and compute the normal
N of the triangle through those points as follows:
( )
( ) ( )
012
3
zz
z
H++
=QQQ
( ) ( )
10 20
=-´-NQQ QQ
.
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.
Other(Considerations(
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
sharp discontinuities.
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
wont 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.
14
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.
1.7( Orientation(
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 thats
where the similarities end.
Myth(BustingQuaternions(
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, youll 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
doesnt 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
1
C
and
2
C
continuity is less important and explains why many engines
dont 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
rotational change
Δt
R¢
is computed as shown in Listing 1.3:
Listing 1.3. Computing Rotational Change
Vec3 angVelAxis(mLastKnownAngularVelocityVector);
// 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
blending technique:
( )
Δmag dir
quat ,
tt
RRTR
¢¢¢
=
(Impact of angular velocity)
Δ0tt
RRR
¢
=
(Rotated from where we were)
Δ0tt
RRR
¢¢¢
=
(Rotated from last known)
( )
ˆ
slerp , ,
ttt
RTRR
¢
=
. (Combined)
This holds true for
ˆ1.0T<
. Once again,
ˆ
T
is clamped at 1.0, so the math simplifies when
ˆ
T
>= 1.0:
Δ0tt
RRR
¢¢
=
. (Rotated from last known)
Two(Wrong(Turns(Dont(Make(a(Right(
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).
1.8( Advanced(Topics(
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.
Integrating(Physics(with(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, youll end up with cases where the two kinematic states dont
perfectly match. At that point, use the techniques in this gem to resolve the two realities.
16
Server(Validation(
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 actors expected behavior
to help identify cheaters.
Who(Hit(Who?(
Imagine player A (local) shoots a pistol at player B (remote, slow update). If implemented poorly, player
A has to leadthe 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 As hit request is valid from client As 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.
Articulations(
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 thats 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
reckoning.
Path-Based(Dead(Reckoning(
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
is,
ˆ
T
, as well as how fast time is changing,
. When applicable, this technique can significantly reduce
bandwidth. Moyer and Speicher [2005] have a detailed exploration of this topic.
Delayed(Dead(Reckoning(
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.
Subscription(Zones(
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.
1.9( Conclusion(
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
can be.
Special thanks to David Guthrie for all of his contributions.
References(
[Aronson 1997] Aronson, Jesse. Dead Reckoning: Latency Hiding for Networked Games”.
Gamasutra, September 19, 1997. Online at http://
www.gamasutra.com/view/feature/3230/dead_reckoning_latency_hiding_ for_.php.
[Cado 2007] Cado, Olivier. “Propagation of Visual Entity Properties Under Bandwidth Constraints”.
Gamasutra, May 24, 2007. Online at http://www.
gamasutra.com/view/feature/1421/propagation_of_visual_entity_.php.
18
[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,
2006.
[Van Verth and Bishop 2008] Van Verth, James and Bishop, Lars. Essential Mathematics in Games
and Interactive Applications: A Programmers Guide, 2nd edition. Morgan Kaufmann, 2008.
... Bei der Bewegungsextrapolation wird die vorher ausgeführte Bewegung eines Objekts bzw. Knotens über eine bekannte Endtransformation hinaus fortgesetzt [17] Prädiktionsfehler von etwa 5-7% im Vergleich zu einer Extrapolation über Bézierkurven auf [32]. ...
... Frameraten bezeichnet [32]. ...
Thesis
Full-text available
Im Rahmen dieser Masterarbeit wird nach Strategien zur Optimierung der feinmotorischer Bewegungssynchronisation in verteilten Systemen eines Netzwerks recherchiert und diese in einer Anwendung implementiert. Die Anwendung soll in der Lage sein, feinmotorische Hand- und Fingerbewegungen über ein Finger-Tracking-System zu erfassen und diese hinterher visualisieren. Anschließend soll die Software die Handbewegungen unter mehreren zugeschlossenen Rechnern in einem Netzwerk replizieren. Bei dieser Bewegungsreplikation sollen verschiedene Optimierungen angewandt werden und Netzwerkmetriken sowie Transformationsabweichungen der Hände und Finger aufgezeichnet werden. Abschließend werden die verwendeten Optimierungen in der Software ausgewertet, die Ergebnisse dieser Auswertung vorgestellt und diskutiert.
... It predicts the state of an object based on the latest position, velocity, and acceleration, and is widely used in the fields of aviation and navigation [41]. Curtiss Murphy [42] uses projective velocity blending, which mixes the newly acquired velocity with the current velocity, and predicts the position combined with the time variable. The KF is an algorithm that estimates the state of a system from measured data. ...
... The algorithm proposed by Curtiss Murphy [42] uses a fixed update rate to implement the DR algorithm. In HDVGE, the client uploads the data to the server only when its status data changes. ...
Preprint
Due to their strong immersion and real-time interactivity, helmet-mounted VR devices are becoming increasingly popular. Based on these devices, an immersive virtual geographic environment (VGE) provides a promising method for research into crowd behavior in an emergency. However, the current cheaper helmet-mounted VR devices are not popular enough and will continue to coexist with PC-based systems for a long time. Therefore, a heterogeneous distributed virtual geographic environment (HDVGE) could be a feasible solution to solve the heterogeneous problems caused by various types of clients, and support implementation of virtual crowd evacuation experiments, with large numbers of concurrent participants. In this study, we developed an HDVGE framework and put forward a set of design principles to define the similarities between the real world and the VGE. We discussed the HDVGE architecture and proposed an abstract interaction layer, a protocol-based interaction algorithm and an adjusted dead reckoning algorithm to solve the heterogeneous distributed problems. We then implemented an HDVGE prototype system focusing on subway fire evacuation experiments. Two types of clients are considered in the system, PC and all-in-one VR. Finally, we evaluated the performances of the prototype system and the key algorithms. The results showed that in a low-latency LAN environment, the prototype system can smoothly support 90 concurrent users consisting of PC and all-in-one VR clients. HDVGE could serve as a new means of obtaining observational data about individual and group behavior in support of human geography research.
... It predicts the state of an object based on the latest position, velocity, and acceleration, and is widely used in the fields of aviation and navigation [41]. Curtiss Murphy [42] uses projective velocity blending, which mixes the newly acquired velocity with the current velocity, and predicts the position combined with the time variable. The KF is an algorithm that estimates the state of a system from measured data. ...
... The algorithm proposed by Curtiss Murphy [42] uses a fixed update rate to implement the DR algorithm. In HDVGE, the client uploads the data to the server only when its status data changes. ...
Article
Full-text available
Due to their strong immersion and real-time interactivity, helmet-mounted virtual reality (VR) devices are becoming increasingly popular. Based on these devices, an immersive virtual geographic environment (VGE) provides a promising method for research into crowd behavior in an emergency. However, the current cheaper helmet-mounted VR devices are not popular enough, and will continue to coexist with personal computer (PC)-based systems for a long time. Therefore, a heterogeneous distributed virtual geographic environment (HDVGE) could be a feasible solution to the heterogeneous problems caused by various types of clients, and support the implementation of spatiotemporal crowd behavior experiments with large numbers of concurrent participants. In this study, we developed an HDVGE framework, and put forward a set of design principles to define the similarities between the real world and the VGE. We discussed the HDVGE architecture, and proposed an abstract interaction layer, a protocol-based interaction algorithm, and an adjusted dead reckoning algorithm to solve the heterogeneous distributed problems. We then implemented an HDVGE prototype system focusing on subway fire evacuation experiments. Two types of clients are considered in the system: PC, and all-in-one VR. Finally, we evaluated the performances of the prototype system and the key algorithms. The results showed that in a low-latency local area network (LAN) environment, the prototype system can smoothly support 90 concurrent users consisting of PC and all-in-one VR clients. HDVGE provides a feasible solution for studying not only spatiotemporal crowd behaviors in normal conditions, but also evacuation behaviors in emergency conditions such as fires and earthquakes. HDVGE could also serve as a new means of obtaining observational data about individual and group behavior in support of human geography research.
... Inconsistencies can have a negative impact on player performance and experience [3,15], such as the confusion caused by sudden warps in position, the frustration of shooting directly at another player and missing [4], or the bafflement of suffering damage from a grenade while protected by an invincibility shield [1]. ...
... There are significant tradeoffs between these solutions, and to-date, their impact on players' experience has received very little attention. Warping may affect players' immersion in the game world, since a player's attention may be drawn toward any sudden discontinuities in the position or motion of objects in the game [15]. A player may also lose context, for example, if an avatar that was in front of him is suddenly behind him, out of his field of view. ...
Article
Full-text available
Networking is a key component of digital games, with many featuring multiplayer modes and online components. The time required to transmit data over a network can lead to usability problems such as inconsistency between players' views of a virtual world, and race conditions when resolving players' actions. Implementing a good consistency maintenance scheme is therefore critical to gameplay. Sadly, problems with consistency remain a regular occurrence in multiplayer games, causing player game states to diverge. There is little guidance available on how these inconsistencies impact player experience, nor on how best to repair them when they arise. We investigate the effectiveness of different strategies for repairing inconsistencies, and show that the three most important factors affecting the detection of corrections are the player's locus of attention, the smoothness of the correction and the duration of the correction.
... More sophisticated approaches exists e.g. curve fitting or position bending to predict movement trajectories [23] [16] [19]. ...
Thesis
Full-text available
Massively multiplayer online role-playing games (MMORPGs) allow thousands of players to interact with each other in a large-scale virtual environment. Interest management is an important technique used to raise the scalability of a game by limiting the amount of information transmitted to the players according to their relevance. In this paper, we focus on the problem of performing interest management during combats, which are highly interactive and fast-paced events. We have developed MMOnkey, a MMORPG framework, which we use as middleware for implementation, demonstration, and evaluation of MMORPG concepts. We then developed a combat state-aware interest management (CSAIM) system in MMOnkey which can dynamically adjust update rates based on the current game context, thereby maximizing the utility in the trade-off between consistency and performance. Our interactive demo client visualizes the interest area adjusted based on players actions. The effectiveness of CSAIM is demonstrated by evaluations on different scenarios.
... An interest area in CSAIM has high frequency and low frequency areas, as depicted in Figure 3 and Figure 4. High frequency areas are painted in green. In order to smoothen the movement of low frequency, we employ dead reckoning methods to interpolate the positions [4]. Dead reckoning lacks accuracy compared to high frequency updates and should only be used for data of lesser importance. ...
Conference Paper
Full-text available
Massively multiplayer online role-playing games (MMORPGs) allow thousands of players to interact with each other in a large-scale virtual environment. Interest management is an important technique used to raise the scalability of a game by limiting the amount of information transmitted to the players according to their relevance. In this paper, we focus on the problem of performing interest management during combats, which are highly interactive and fast-paced events. We have developed a combat state-aware interest management (CSAIM) system which can dynamically adjust update rates based on the current game context, thereby maximizing the utility in the trade-off between consistency and performance. We have implemented CSAIM in MMOnkey, our MMORPG research framework. Our interactive demo client visualizes the interest area adjusted based on players' actions.
... So, it is not necessary to sort the frame dataset. For reducing the communication between client and server, the algorithm uses a dead reckoning approach [33], in which the server side can estimate an object's current position by using previous information: location, speed and direction. Even in an online application, the frame data are kept for historical records, enabling visualization rewinding. ...
Conference Paper
Full-text available
Urbanization is accelerating worldwide, giving rise to serious traffic problems. Traffic wave, known as stop-and-go traffic or phantom intersection, is one of the most significant traffic oscillation patterns studied in Traffic Engineering. Usually these studies are numerical experiments that investigate specific places, such as a crossroad or a highway section, and their findings cannot, therefore, be easily applied to sensing device data in a systematic computational approach. In this regard, visual analytics can help by combining automated analysis with interactive visualization for effective understanding, reasoning, and decision-making. In this paper, we present a novel approach for visualizing traffic oscillation patterns by visualizing the objects' movement in space over time, inspired by vector field visualization. We propose an algorithm to control and synchronize the visualization time; a systematic stepwise methodology for exploring sensing device data; and a visualization tool that computes the trajectory data in parallel on the GPU at interactive frame rates. Moreover, our approach is designed to support both batch-processed and streaming data applications. We also present the benefits and limitations of our visualization proposal based on domain expert feedback. Finally, we present performance tests with very encouraging results to support our approach.
Chapter
Many large-scale online genre games such as Massive Multi-player Online Role Playing Game (MMORPG) are attracting attention in the game market. In a game server connected to hundreds or thousands of users, a large number of packets come and go between the server and the client in real time. For the server to endure these loads, IOCP (Input/Output Completion Port) and multi-thread are necessary. This paper implements a simple MMO Game Server using IOCP and evaluates its performance. Also, IOCP packet design and processing method are presented. The Simple MMO Game Server implemented in this paper also supports multi-thread synchronization and dead reckoning.
Book
Each edition of Introduction to Data Compression has widely been considered the best introduction and reference text on the art and science of data compression, and the fourth edition continues in this tradition. Data compression techniques and technology are ever-evolving with new applications in image, speech, text, audio, and video. The fourth edition includes all the cutting edge updates the reader will need during the work day and in class. Khalid Sayood provides an extensive introduction to the theory underlying today's compression techniques with detailed instruction for their applications using several examples to explain the concepts. Encompassing the entire field of data compression, Introduction to Data Compression includes lossless and lossy compression, Huffman coding, arithmetic coding, dictionary techniques, context based compression, scalar and vector quantization. Khalid Sayood provides a working knowledge of data compression, giving the reader the tools to develop a complete and concise compression package upon completion of his book. New content added to include a more detailed description of the JPEG 2000 standard New content includes speech coding for internet applications Explains established and emerging standards in depth including JPEG 2000, JPEG-LS, MPEG-2, H.264, JBIG 2, ADPCM, LPC, CELP, MELP, and iLBC Source code provided via companion web site that gives readers the opportunity to build their own algorithms, choose and implement techniques in their own applications.
Exposing Actor Properties Using Nonintrusive Proxies". Game Programming Gems 6
  • Matt Campbell
  • Curtiss Murphy
Campbell, Matt and Murphy, Curtiss, "Exposing Actor Properties Using Nonintrusive Proxies". Game Programming Gems 6. Charles River Media, 2006.
Drop in COOP for Open World Games
  • Glenn Fiedler
Fiedler, Glenn. "Drop in COOP for Open World Games". Game Developer's Conference, 2009. Online at http://gafferongames.wordpress. com/.
A Road-Based Algorithm for Dead Reckoning
  • Dale Moyer
  • Dan Speicher
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, 2006.