vistal Posted June 1, 2016 Share Posted June 1, 2016 I am working on a multiplayer game with socket.io and phaser. I have done a proof of concept by implementing a "cheatable" multiplayer whereby the server simply accepts positions from the client and relays them back to other clients which works quite well. I am now in the process of refactoring all of it to run p2.js (independent of phaser) on the server, and am trying to figure out some timing problems/questions. I also have some general implementation questions not specific to phaser but that perhaps you guys can provide insight on. Layout of application and questions: Node server running socket.io and p2.js. Client running phaser. I am storing the input captured in the update function into an array that is passed to the server every so often and then cleared. I want to also store a time stamp in this array each time a "command" is issued. When the server receives this array I intend to add a third value which is time received. Finally, I intend to pass this out to the other clients with a slight delay (interpolation). I want the clients to see themselves in the current time and everyone else slightly in the past (so that I can use their actual keyboard input to reflect their movements). Questions: 1) Should I be relying on a client time stamp at all? I suppose its possible to fake the time stamp on commands and thus wreak havoc if one wanted to cheat? 2) If I can rely on a client time stamp, how do I get one that is accurate in relation to the server? I have tried this.time.now, but it seems to depend on time of client load and doesn't even sync on a LAN. 3) I intend to calculate the average packet delay (still working on this) and therefore should be able to throw out outrageous time stamps from the client. I am also considering issuing the game start packet, and then giving it a 30 second delay for everyone to sync up. How could I reset phaser time to an absolute time not to start until the "start time"? 4) Should I be using physics time or wall clock time? Clearly I can't use game time since that appears to get hung when a window is minimized? 5) How is physics time calculated? Is this based on FPS? I wonder this because I wonder if I need to implement p2.js independent of phaser in the client as well? I'm aware I'm asking some complex questions that are somewhat outside of the scope of phaser, but I was hoping you guys could help me. This is a learning project just to see if I can do it, so anything you could point me to would be greatly appreciated. Thank you in advance, Vistal WombatTurkey and ecv 2 Link to comment Share on other sites More sharing options...
ecv Posted June 1, 2016 Share Posted June 1, 2016 I have no idea how these multiplayer network schemes work, so take my advice with a grain of salt, but regarding points #1&2: Why not use delta times instead? I mean, don't check for actual time stamps, but a time counter provided by the server, to which clients should add to and return its increment to the server. I have no idea if this could be faked by the clients, but I'd think that changing system's time wouldn't affect this. Link to comment Share on other sites More sharing options...
vistal Posted June 6, 2016 Author Share Posted June 6, 2016 Alright, I'll update this if I discover further relevant bits, but in case anyone finds this later anyway I have solved this for now by: I consider time the client hits the command to be irrelevant (for it to be relevant would open up cheat possibilities and make it so that I had to step backwards in the physics). If I consider the time stamp on when client pressed the key in the server calculations, it opens up the possibility for people to spoof packets to make commands appear in the past and alter the physics. I stopped sending an array and started just sending an packet every time a command is pressed during an update cycle on the client. The command is processed on the server as if it was hit immediately prior to the next update loop on the server after it was received. I do this by maintaining a tick counter every time the physics loop on the server makes a pass on the server. Every command received from the client has the current tick number + 1 applied to it by the server. If the command tick number = the current server tick counter then the command is processed. If the command tick is > the current server tick counter, the command is queued. If the command tick is < the current server tick, it is just thrown out. I have not yet started rendering on the client, but when I do, i will have to make sure that the correction on client position vs server position accounts for the fact that the client is operating slightly ahead of the server for their current position. I'll make the gap required before correction wide enough that it shouldn't matter if the only difference is the round trip time on the packet. As a note to anyone using p2.js on a server and phaser on the client, be aware p2.js uses meters for distance while phaser uses pixels. Currently working out how to convert between the two. If anyone knows the exact formula phaser itself uses it would be appreciated, but I'm going to do some digging. Link to comment Share on other sites More sharing options...
WombatTurkey Posted June 6, 2016 Share Posted June 6, 2016 These are some good questions. I'm going to page several people that I think can help out @rich @drhayes @lewster32 @rgk @Rezoner @jbs Link to comment Share on other sites More sharing options...
lewster32 Posted June 6, 2016 Share Posted June 6, 2016 It's been mentioned before but this is an excellent article covering much of the collected wisdom of gaming network code development. WombatTurkey 1 Link to comment Share on other sites More sharing options...
drhayes Posted June 6, 2016 Share Posted June 6, 2016 Unfortunately, I've never worked on a multiplayer game so only know the theoreticals. These are all great questions that line up with lots of stuff I've read. lewster's already posted my #1 resource for multiplayer reading, here's my #2: http://gafferongames.com/networking-for-game-programmers/ Client/server time is just never gonna sync, maybe not even on the same machine in two separate processes. I think you'll just have to experiment w/r/t time. If you're using socket.io you won't get messages out of order, so client time should always move forward. Your approach there sounds great to me. What kind of game are you making? Link to comment Share on other sites More sharing options...
vistal Posted June 8, 2016 Author Share Posted June 8, 2016 @lewster32 and @drhayes thank you for the articles. I have been spending some quality time with them and they are quite helpful. @drhayes it is a top down space shooter. Think multiplayer asteroids. drhayes and lewster32 2 Link to comment Share on other sites More sharing options...
drhayes Posted June 8, 2016 Share Posted June 8, 2016 Post when you've got something so you can tell us how it's done and we can beta test it for you! Link to comment Share on other sites More sharing options...
Recommended Posts