And so far it seems to be working pretty nicely, the general scheme is this:
On every frame on the client, calculate desired movement vector from keys down, store this in a move_cmd struct, also store the exact time and the frame delta time, struct looks like this:
struct move_cmd {
float time;
float delta;
vector3 moveVector;
}
I then send of this to the server, and then store it in a list of yet to be verified commands. When I receive a response from the server, it contains the current position and the time of the move_cmd that caused the current position to be where it is. I go through the list of move_cmd objects and remove all of the ones that have time that is less then the server response. When it's time to move the model on the client screen i take the last verified server position and add all the moveVectors * delta to it, giving me a predicted position.
It seems to be working pretty well, I still need to interpolate when I predict wrong, but it seems to be working. Now to my two questions:
1) This causes the client and server to basically exchange movement information on every frame, I can compress it a bit and it'll end up to about 800bytes/s, maybe this isn't that much but still feels like a lot?
2) Since the server bases the calculation on the frame time delta given by the client in the message, it feels as if the client could modify the time delta it at will and cheat? Assume that the client puts some type of "man-in-the-middle" attack and changes the part of the message that represents the delta from 0.015 to 1.0 which would make the client run really fast. Is there some other timing/delta I should base the movement of instead?
Edit, addition to question #2: Should I use some kind of heuristic on the server to verify that the client has to move within certain "bounds" or otherwise label it as cheating and boot him, or should I base the movement speeds on some other delta/timing then the frame delta from the client?
And last, is this a good way to go about it or are there other ways of doing input prediction? I've read several articles on the subject (the source engine wiki for example), but none go into detail on how the actual sync:ing of the client and server is done but are mostly high level overviews. The only detailed one I found was the PDF linked earlier (http://web.cs.wpi.ed...mes/bernier.pdf) and that explains a model that is pretty much identical to the one I just explained and have implemented.