here''s how i am doing my networking (or at least planning to), but it''s just a draft so it can change anytime.
this system is very similar to half-life''s. note that i''m only discussing player movement, nothing else such as firing weapons, reloading, etc.
also note that each packet is time-stamped. meaning that it contains the time when it was sent.
a client presses a key move up. every tick_time (which is 50 ms) it checks the state of the move up key. it''s down. so we indicate that in the state packet, and send it off to the server. we also log it in a local buffer for later self-movement prediction, as well as the current time (assuming the clock on the server and each client is in sync).
the server receives that packet some time later (depending on the latency). it understands that we were holding down the move up key, so it does all the necessary calculations and comes up w/ the new position for that player. it sends a packet to that client containing the current server time, the time this state update is from (it''s the time the packet from the client was sent), and the resulting position of the player. it also contains last known positions of other clients and their time (the time at which those positions were valid).
meanwhile, the client want to render the scene (i''ll only discuss his own-position prediction, not other clients). he knows that last world state update (what server send to clients - discussed above) is 0 ms (because it never got one yet. as soon as it will, it will update the clients position and the time that position would''ve been valid - the last_world_state_update time). right now it''s 14 ms. and we have one buffered user command - move up. the date of that command is, let''s say, 7 ms. that means it came AFTER last_world_state_update which is 0 ms, so we apply it. here''s some pseudo code.
start with last authoritative update the server sent to usfor ( each movement that is time stamped after the movement thatpreceded the state update ){ run the movement on the client and predict our new player origin;}set the final origin as the render origin for this frame
now i will talk about lost and our-of-order packets. what i have in mind right now is something like this. each packet is not only time-stamped, but it''s also numbered. so if a packet gets lots, we''ll know. if that happens, we wait for some period of time, hoping that it was an ooo (out of order) packet, meaning it will be here soon. if it does arrive, we apply it. as long as there aren''t any holes (like packets 1, 2, 3, 4, and 6 came: there''s a hole - packet 5), we can send world state updates to the client without a doubt. meanwhile, while we''re wairing for an ooo packet, the client predicts his own position using the logged key presses (or rather key states) w/o any warping. if we''re lucky, and ooo packets arrive and fill in the holes before a certain amount of time (right now i''d say it should be around 150 - 300 ms), we can safely send a correct world state update to the client. if everything goes correcly, there shouldn''t be any errors or differences (other than the errors in limited precision of floats, but that is so little it''s completely unnoticable), so to that client his own movement will appear very smooth w/o any warping (sudden "teleportations").
but what if we''re not lucky, and the packet never makes it? in that case we could either send a request for it, or if there''s enough bandwidth, we could always send each packet twice, or the last method, which so far we (our team, including me) think would be to average out the clients movement. that, of course, can only happen if there aren''t any big holes, or too many of them. which is why there''s another constant (which, atm, is 2), which indicates how many packets may be missing so that the "averaging" algorthim (will be described below) would be left enabled. what that is, is nothing more than just "averaging" our the missing packets. so if packet 5 didn''t come, but in packet 4 and 6 we were moving forward, we will assume that in packet 5 player was also moving forward. that way the maximum error will be the least possible, and since in our game player movement will be very smooth (ie. no sudden changes in directions, low accelerations, etc.), the warping the play may experience will be minimal.
i am kind of tired right now, so i might''ve said something wrong, or just didn''t explain it well, for which i ask your forgivness.
![](smile.gif)
above goes for player movement, but we still have to figure out how to do weapon hit checks. the problem is that we have many "timed" weapons, meaning they will explode only after some time, allowing us to get the explosion sync on all clients and the server. that is very benificial, if used correctly. which is why i talked about it more thoroughly in
this post, asking for your help/suggestions/comments/etc.
thanks for your time, i hope i''ve helped you, and maybe you''ll help me.
![](smile.gif)
ps. sorry for a long post, i usually do that when i want to describe something well (and usually it turns out to be other way around)...
---
shurcool
wwdev