   Client character movement smoothing
  Hello all! First off, great forums and website you've got here, I've picked up quite a bit of info from browsing without an account but I've stumbled into something I really would like to ask you (the community) specifically!I'm working on a simple top-down-ish view 2D game (extremely similar to Legend of Zelda games on the GameBoy, or the original Zelda games). The game itself was made a bit of time ago as a school project, and I've been working on and off on making it work on a network, primarily just to play with my friends, nothing major.The game isn't going to be a fast paced action game, but still needs moderate speed (just as if you were playing a Zelda game).The game is written in Java, and I am using a combination of TCP and UDP to send data. More precisely I'm doing..TCP: *When the client initially connects, sends them data with which they can create a Vector(pretty much an Array List) that contains all the relevant objects to that client (on the current map) that I cleverly call the 'masterList.*When a new object is introduced to the map, sends the clients information to construct that object, and adds it at the end of the 'masterList'*Whenever an object needs to be removed from the 'masterList'UDP:*Whenever an object 'changes' its new state is encoded and sent to the clients. The way this is done is by encoding this object's location in the masterList as well as its new state. The client then receives this information and alters the object at that index of the masterList accordingly. These packets are sent to each client every 66 ms or so (15 packets a second, each one is 5 bytes of header and 6 bytes per object (this does not include UDP header){Is this too big?}).*Current keyboard status is sent to the server. Besides the UDP header it's 3 bytes per packet every time) and I send it every 33 ms (~30 packets a second)Now, I'm having some problem with movement on the client. Even when I have a single person connected on the local network, there is a bit of delay, and that causes the clients objects to sort of jump a little.On the client I run a game engine that mirrors the server's, that fixes some of it, but it's still too noticeable for my tastes. I am wondering if you have any recommendations for this sort of set-up.If you need more specific code samples or anything please let me know and I'd gladly post 'em. I didn't want to clutter up this post, you see!   
  Are you interpolating at all? When it comes to smoothness in network simulations, you often end up sacrificing a bit of accuracy.   ;  I think you're not accounting for latency. When you receive the message, it might have took some time to deliver it after it has been sent, causing the lag you see. You should compute a time difference between when the packet is sent is received by including a time-stamp in the packet, and use it to predict where the entity will be after that period of time. Continue to move the entity towards the last known direction until a new packet is received with the new sync information.   ;  To spodi:I'm afraid I'm not too familiar with that. I'll read up and post back ASAP, though if you could explain it a little, that'd be great.To Momokofan:When a receive the 'update' packet, it includes their current movement status and I continue updating based on that until I receive a new packet. The only variables in movement are "left, right, up, down" and they are all booleans so movement is pretty simple: If the last time I received an update on this object it was moving left, then it'll continue moving left 'till I receive a packet that says otherwise.   ;  You should send more than just up down left right to your client.  The server should send the characters position along with the direction.  So your client can calculate the desired destination, and adjust the movement of the character to arrive at that desired destination.   ;  Typical update packet contains:*Which object 'changed'*That object's status (left right up down)*That object's positionWhen you say calculate the movement required to arrive at that location, you mean that instead of setting the object's position to the one I obtain from the packet, so set so his movement reaches that location?What's the point of that calculation if in a couple of milliseconds I'll get another packet telling me where the object is now, before much change has happened? Should I increase the object's speed every time this distance difference increases so it can catch up? Wouldn't that make the movement look a little weird too?Sorry for all the questions, I like to walk up to vague and be all like "wut?!"EDITOkay, so I read a little on interpolation, is this more or less on the right track?int diffX, diffY; diffX = (int)(obj.x - x);diffY = (int)(obj.y - y); if(diffX != 0)if(Math.abs(diffX) < 10&& Math.abs(diffX) > 1)if(diffX > 0){obj.left = true;obj.right = false;}else{obj.left = false;obj.right = true;}elseobj.x = x;if(diffY != 0)if(Math.abs(diffY) < 10&& Math.abs(diffY) > 1)if(diffY > 0){obj.up = true;obj.down = false;}else{obj.up = false;obj.down = true;}elseobj.y = y;  [Edited by - Zulu Inuoe on January 25, 2010 11:49:29 AM];Quote:I continue updating based on that until I receive a new packeThe problem is that you are now timing and network dependent. If a packet arrives a little late, you will have moved too far in whatever direction.The least jittery implementation is to send the position of the entity. When the client receives the position of the entity, it starts moving in that direction, and it will stop when it reaches the destination, or when a new packet comes in. You may even want to use a little dampening -- move with a velocity such that you'll get 90% of the way to where you want to go by the time the next packet is *supposed* to come in. That way, you will not end up stopping and starting again a lot if the network is jittery.The main drawback is that remote entities will be one round-trip time delay behind on your display. For a Zelda-like game, that's likely perfectly acceptable.;  Woo! That worked wonders! And you even saved me a byte per object! (The one with the booleans)Here's what I wrote, in case I did something stupidpublic void clientUpdate(long time){float diffX, diffY;diffX = x - targetX;diffY = y - targetY; if(Math.abs(diffX) > 20)x += speedX * time;else{speedX = 0;x = targetX;}if(Math.abs(diffY) > 20)y += speedY * time;else{speedY = 0;y = targetY;}}This is the update done on the object by the client.'time' here is just the time passed since the last iteration of the game looppublic void clientSet(long time, int targetX, int targetY){this.targetX = targetX;this.targetY = targetY; speedX = .9f*(targetX - x)/time;speedY = .9f*(targetY - y)/time;}'time' in clientSet is the average time between packetsI want to play with the numbers a little in clientUpdate and I'm sure that'll better performance, but already it's doing very well. Thanks again   