javascript - Multiplayer game movement synchronization -


i'm working on multiplayer game , i'm having problem synchronizing players.

when player presses 1 of move keys (w,a,s,d) client sends packet pressed button, server sets velocity according pressed key , sends nearby players new velocity.

when player release key clients sends packet, server sets player velocity 0,0 , sends position , velocity nearby players.

so problem when release key, of time player jumps back.

how fix this?

i'm using socket.io.

client side:

   socket.on('positionentity', function (data) {         console.log((data.x - entities[data.id].x)+" "+(data.y - entities[data.id].y));         entities[data.id].setposition(data);     });      $(document).keyup(function(e) {         if (e.keycode == 87) {             keys.w = false;             socket.emit("stopmove", {dir: 0, time: date.now()});         }          if (e.keycode == 65) {             keys.a = false;             socket.emit("stopmove", {dir: 1, time: date.now()});         }          if (e.keycode == 83) {             keys.s = false;             socket.emit("stopmove", {dir: 2, time: date.now()});         }          if (e.keycode == 68) {             keys.d = false;             socket.emit("stopmove", {dir: 3, time: date.now()});         }     });      $(document).keydown(function(e) {         if (e.keycode == 87 && !keys.w) {             keys.w = true;             socket.emit("startmove", {dir: 0, time: date.now()});         }          if (e.keycode == 65 && !keys.a) {             keys.a = true;             socket.emit("startmove", {dir: 1, time: date.now()});         }          if (e.keycode == 83 && !keys.s) {             keys.s = true;             socket.emit("startmove", {dir: 2, time: date.now()});         }          if (e.keycode == 68 && !keys.d) {             keys.d = true;             socket.emit("startmove", {dir: 3, time: date.now()});         }     }); 

server side:

socket.on('startmove', function(data) {     if (data.dir == 0) socket.player.setmotiony(-5);     if (data.dir == 1) socket.player.setmotionx(-5);         if (data.dir == 2) socket.player.setmotiony(5);     if (data.dir == 3) socket.player.setmotionx(5);      io.sockets.emit("positionentity", socket.player.serializeposition()); });  socket.on('stopmove', function(dir) {     socket.player.setmotionx(0);     socket.player.setmotiony(0);      io.sockets.emit("positionentity", socket.player.serializeposition()); }); 

this complex task working on , i've done part of pet project ;)

you're working on client-server architecture game server final authority on game logic , decisions. way handling rendering make sudden changes in velocity , direction apparent due latency (as have noticed!)

the trick buffer movement information of remote players render player slight delay. kept things primitive in project , used positional data, not acceleration or velocity. example, when player moves on machine command not instantly sent receive acknowledgement, moves , on next tick of networking send loop (10 ticks per second) position fired server updates clients in vicinity new position. these clients have buffer each "remote" player stores each position time (100 milliseconds) before rendering update. in way client rendered slight delay can interpolate (smooth transition of sprite/model) between each positional co-ordinate achieve smooth motion illusion of velocity , acceleration.

a basic interpolation function client code. system queued 2 updates each remote player @ most, index 0 in update array older of two. index 0 might remote player position 0ms , index 1 remote player position @ 100ms.

interpolate: function() {   var timedifference = new date().gettime() - this.serverupdates[1].time;   // percentage of time passed since update received (i use 100ms gaps)   var interpercent = (timedifference) / 100;    // latest updates (index 1 newest state)   var s1 = this.serverupdates[0],     s2 = this.serverupdates[1];    // need lerp between values provided in latest update , older 1   var p = (new vector3(s2.position)).subtract(new vector3(s1.position));   p = p.timesscalar(interpercent);    // new position older lerped toward newer position lerp    //percentage time passed    this.position = new vector3(s1.position).add(p);    // update rotation in smooth manner   var rotationdifference = (s2.rotation - s1.rotation);   if (rotationdifference && rotationdifference != 0) {     this.rotation = s1.rotation + (rotationdifference * interpercent);   } }, 

in code receiving updates approx 100ms apart, @ time 0 position s1 , time 100ms s2 position. if 50ms have passed since received s2 entity 50% between 2 positions. fine need may not work out in other types of games or might need tweaking.

these resources excellent start explain networked games , dealing latency, you'll amazed @ difference implementing interpolation , extrapolation have on game smoothness in remote clients.

http://gafferongames.com/networking-for-game-programmers/what-every-programmer-needs-to-know-about-game-networking/

https://developer.valvesoftware.com/wiki/latency_compensating_methods_in_client/server_in-game_protocol_design_and_optimization <- good!

https://developer.valvesoftware.com/wiki/lag_compensation

good luck :)


Comments

Popular posts from this blog

plot - Remove Objects from Legend When You Have Also Used Fit, Matlab -

java - Why does my date parsing return a weird date? -

Need help in packaging app using TideSDK on Windows -