Skip to main content
gamedev.net
🔒 Locked

Implementing client side prediction

Started by Promit Mar 9, 2004 at 6:27 PM 2 replies 1.2k views
Original Post
Promit
Promit
I''ve been reading a lot about client side prediction and dead reckoning, since it appears in essentially every single network coding article in existence. So I''m just laying out the ideas for how to actually go about implementing it. Now, the first problem is exactly where prediction is supposed to be done. Obviously it happens on the client, but who is responsible deciding where players "probably are"? Should that be handled in the networking code? Or should it be part of the main game engine? Second, what criteria will I be using to predict? A calculated velocity vector that just keeps going forward (think FPS here)? And when the next network update comes in, do I just snap the players back? Also, what should prediction actually be used for? Just rendering, or something else? Do I collision detect predictions, or not? (and a related question, do I collision detect on the client at all?) In short, should the client simply take whatever velocities it last had and continue to apply them until it gets a message from the server to change? And should that be done in the network code or the master game engine?
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
hplus0603
hplus0603
There simplest prediction model is doing it in rendering.

Your physics engine keeps track of where the last two updates were in time and space. The rendering engine then asks for the position of the object at some time, which typically is after what you have -- so you extrapolate from the two points you have, linearly, and render there.

I e:


struct TimePos {
Time time;
Pos pos;
};
struct Entity {
TimePos data[2];
};

// Call this function when you get an update for an
// Entity at some specific time (which will be in
// the past).
void onReceive( Entity * ent, TimePos const * nu )
{
ent->data[0] = ent->data[1];
ent->data[1] = *nu;
}

void onGetPosAtTime( Entity * ent, Time t )
{
if (ent->data[1].time == ent->data[0].time) {
// Avoid division by zero
return ent->data[1].pos;
}
return ent->data[1].pos +
(ent->data[1].pos - ent->data[0].pos) *
(t - ent->data[1].time) /
(ent->data[1].time - ent->data[0].time);
}


You may want to smooth the interpolation, so that the player does not jump around when receiving updates.
enum Bool { True, False, FileNotFound };
kindfluffysteve
kindfluffysteve
It is probably good idea to use time stamps.

then you can do this:

the update includes these things:
Timestamp
pos
vel
acc

newPos=oldPos + Time(vel+0.5*acc*Time);   


where Time is time difference between last update and the present.

Then this system always estimates to the best of the clients ability- the current location of an object.

Jerkiness continues:
There will still be jerkyness because we the estimate of the dynamics update previous to the most recent will up until the change over to the new - be predicting one thing, and the newest one will be predicting something slightly, but distinctly different for the same current time.

Remember that the curret time is always after the last update since there is lag delay.

To counter this jerkiness I base the 'avatar' of the foreign clients position on a spring model - the physics for such a network avatar are simply:

Acc=THE_CLEVER_PART();
vel=vel+acc*dt;
pos=pos+vel*dt; where dt is the small time between frames.


the 'clever part' in all this is to use a spring model that applies acceleration forces to the network object based on the most current *Desired* position and velocity. so the spring forces act to move the network object and also act to match acceleration - to make both position and velocity the same.

This is how I do it. and it seems to work somewhat well.

[edited by - kindfluffysteve on March 10, 2004 8:44:03 PM]

[edited by - kindfluffysteve on March 10, 2004 8:45:51 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.