Client/Server movement payload / verification


skeezix

Internal Development
Joined
Mar 11, 2003
Messages
8,070
Website
www.codejedi.com
hey guys,


This is a problem we all come across during games development (be it 3d or 2d, from quake to civilization to WoW to whatever.) I'm sur eits well documented around, but we all have a strategy for it. Whats yours?


ie:


Client is a player-client; server could be another player, or a central server, or whatevberl doesn't matter.


Not including 'action' payloads, such as 'open door' or 'disarm bomb' or whatever, just movement (ie: action payloads imply already verified locations, and I'm more worried about motion events.)


Most clients or servers (depending on the motion model) will project other players motion (straight line, even into a wall say), on the off chance they're "right" and thus better hadnle low pingtime players, etc. (A classic problem is players flying right through walls, so you have to be careful server side to not verify point by point, but along the whole line of motion..)


Does your..


i) Trusting; server trusts the clients, ie: debug mode, or 'didn't finish the netcode' mode :) In commercial games, this is not the case anymore, but was back in the Everquest days ;)


ii) Client report in packet "I am at (map,x,y,z)" (possibly with "dmap, dx, dy, dz" for delta sake as well)? And the server then.. determines last timestamp and location, and current timestamp and reported location, determines shortest map between points (djikstra's or other algorithyms), and works out validity if you could have made the journey?


iii) Client reports delta map,x,y,z and server works out where you are .. this can be a problem for lost packets.


iv) Something else?


I tend to use (ii) but its a lot of work doing that level of verification, and of course all the clients are spamming away with 'I'm at (x,y,z)!" all the time, but network games are always heavily hammering the network..


Any well known strategies that are used?


jeff
 
Interesting topic.


I have yet to write my first multiplayer game, so I can't give any personal impressions, but I have read about the topic.


For example here is an overview of how Valve does this in the Source engine (which I find to have a pretty good netcode): https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking


That wiki also contains a few other pages on lag compensation, interpolation, prediction, etc. which could be interesting as well.


Basically they seem to do client side calculation of the game (prediction) and sending mostly user input to the server for verification and in turn the server sends an updated delta world package back, which the clients again uses to "correct" his own game world with. Then there is lag compensation for user interactions (such as hits/shots), in which the server keeps a one second history of all events and on an incoming critical package can revert the world to the state this package was created on the user's side to check for hits and then go back to the original state (this is why one sometimes gets shots after turning a corner).
 
The Collector was "trusting"... Nothing was timestamped, but then I used TCP over UDP. But then The Collector was just a crap game :)


Master Class is going to full-sync both players "parties" at the start of battle, then after each turn, I think we'll probably CRC check the party status to confirm nobody's cheating - at least in battle. I'm not sure how we'll enforce participants going in with unmodified parties. I guess that's slightly different though because MC will be turn based, and there's no massive requirement to be pumping tons of data continuously across the network.
 
http://en.wikipedia..../Dead_reckoning + bit flags for movement/action


It's possible to reduce the sending of "position ping" packet, by trying keeping track of client's packet loss or latency.


However, my last network code has been so long ago that I'm interested in modern alternatives as well.
 
Last edited by a moderator:
The Collector was "trusting"... Nothing was timestamped, but then I used TCP over UDP. But then The Collector was just a crap game :)


Master Class is going to full-sync both players "parties" at the start of battle, then after each turn, I think we'll probably CRC check the party status to confirm nobody's cheating - at least in battle. I'm not sure how we'll enforce participants going in with unmodified parties. I guess that's slightly different though because MC will be turn based, and there's no massive requirement to be pumping tons of data continuously across the network.

So Collector did not handle at all well if there was high variance in transport time eh? ie: One guy was at 10ms, another guy at 700ms, total disaster? Or worked out okay, even being simple code?


I tend to have a policy of 'trust the server' and 'do not trust the clients'; if the server is lieing, you have bigger problems :)


jeff
 
So Collector did not handle at all well if there was high variance in transport time eh? ie: One guy was at 10ms, another guy at 700ms, total disaster? Or worked out okay, even being simple code?
No, it was pretty naff. It even got desync'd on a LAN! I thought the TCP relaiability would keep me in sync, but one of the other problems with TCP is the way it buffers packets. There's an option to change it I think, but I hadn't set it. It might have been better on UDP, I'm not sure.


The game was a miserable failure on the network side... and not too hot on the gameplay side (as Foxblock helpfully pointed out in my Collector Plus thread, hence why the project got ditched)
 
Basically they seem to do client side calculation of the game (prediction) and sending mostly user input to the server for verification and in turn the server sends an updated delta world package back, which the clients again uses to "correct" his own game world with. Then there is lag compensation for user interactions (such as hits/shots), in which the server keeps a one second history of all events and on an incoming critical package can revert the world to the state this package was created on the user's side to check for hits and then go back to the original state (this is why one sometimes gets shots after turning a corner).

I do something like this in my advancedFlyer gamenode test. Basically the player can move freely locally, sending keypresses to the server, which keeps its own model of the game and sends global state to the clients. All actual game logic outside player movement happen only on the server. I'd very much like to learn about more advanced techniques. This is just something I came up with trying to make a synchronous game test for gamenode.
 
b-zar .. sending 'global state' (hacked client can know too much about opponents?) and trusting movement .. never done anymore for 'big titles'; the hard part of course is when a modded client just leverages all your shared libs/dll's so your own code is being used against you.. roper packets, everythign looks fine, but being operated for evil :)


I'm not worrying about those pathological cases (thats where you have to have aimbot-detection, looking for unusualklty responsive players etc) :)


I'm figuring on the usual..


-- send delta


-- send actual locations as far as client is concerned


-- server uses timestamp to validate if movement seems possible


-- server could send back model actuals to client, and if client says woa, I'm way the hell out', then client can take servers side ('jitter')


-- server sends visible actuals plus recent delta history to all other clients (?) .. so they can know pretty close where visible guys are, and can make the next few seconds movement guesses based on recent deltas (?)


.. server controls who gets what, no massive world dump (so much easier, alas..), just sendinmg interesting bits.


ie: I assume, if its a modded client, whatever.. as long as they're responding more or less like real palyer (not too fast, not too accurately for fps say), and they have limited information .. then at best they're still onyl so much 'better off' than other players.


And the game I'm thinking of writing is odl school dumb anyway, but I like to architecture it like its bigger :p


jeff
 
That code is for an example of using gamenode, so there's some things missing to keep it simpler to read. Of course the deltas could be filtered for each player's field of view. If your game is 2D, you can do basic FOV with one lengthSquared and two 3x3 matrix multiplications per object, which is quite fast. Didn't want to sway the example value of the code with that though :)


The movement is actually not trusted. All movement that goes to the clients from the server is calculated by the server based only on client provided key presses. Basically all a hacked client can do there is fake input, but there's really no way around that. It still has to abide by the game's rules.


Would your system be "first come first served" regarding validation? If a client says player 1 moved from A to B in the time interval (t-4, t) and then another client comes in and says player 2 moved from C to D in the time interval of (t-2, t-1). In the case that player 2 would've blocked player 1 if the movement was known before player 1 submitted his movement, would your system move player 1 back (even though his movement was already validated), tell player 2 "tough luck, you got blocked by player 1" or ignore the collision and let both be on their merry way?
 
I'm not quite sure on the type of game you're making, but how would that cater for things like inventory and projectiles? For example, medi-kits and ammo would need to be somewhat processed on the server.


B-ZaR, how do you cater for lost packets if you're only checking keypresses? I remember playing Killer Instinct in a version of Mame with Killiaria (spelling?) and we got out of sync a couple of times.
 
I leave lost packets to TCP. Since gamenode is a web socket thingy, I can rely on every packet getting through.
 
Most games historically have used UDP -- faster, allow loss and manage it yourself, and easier to implement in discrete hardware or simplified environments. tcp retransmit/ordering is awesome, but can clog things up.. ie: if you're doign high speed positional update spam for a FPS client, then losing a few packets here or there is irrelevent, you just need to get them fast. If you use tcp for that, you risk clogging up the whole feed because one got lost.


Depends on the type of game .. my games tend to be slower paced (turn based or slow paced action) so I can live with tcp :)
 
TCP is fine most of the time, and with web stuff you really don't have a choice. I do recognize the latency and throughput benefits UDP brings, especially if the connection is bad. It's not really unheard of to do synchronous (direct movement input) multiplayer games on TCP. It's not optimal, but if it suffices it makes things quite a bit simpler (with not needing to manage datagram splitting and stuff).
 
Really the trick is..


Given..


Say you get a packet every 300ms (3-4/second) and its a cosntant movement speed for sake of argument.


After X packets (1,2,3?) you just assume constant accerleration (coudl be 0,m coudl be whatever he's been doing lately)? or assume equal speed? until he impacts a wall, then just stand there like a fool until you get an update?


I guess prediction, on a naive level shoudl be .. if he's done the same thing for a second or tow, juat asusme its good for another second or two and then stop like a fool; you want to allow for a bit of leinaincy, but you can't go assumign 30s of same motion based on the last sliding window of 1sec; maybe a window of 1sec buys you another wndow of 1-2sec, just enough to hopefulyl get another packet or two in to correct your assumptions. If it ends up being 3-04 secs without an update, just give up and assume full stop?


I'll look into it when I get time and see how it works in the field. Random movement bot ftw :)


jeff
 
Back
Top