Tufan Posted May 22, 2017 Share Posted May 22, 2017 I'm working on a multiplayer game but player seems like teleporting when server sends new position. How can i make movement smooth? Here's my movement algorithm: Server (running every 1000/60ms): var updated = false; var speed = 300/60; if (this.player.cursors.up){ this.y -= speed; updated = true; } if (this.player.cursors.down){ this.y += speed; updated = true; } if (this.player.cursors.left){ this.x -= speed; updated = true; } if (this.player.cursors.right){ this.x += speed; updated = true; } if (updated){ ...broadcast new x,y.... } Client: var x = ..serverX..; var y = ..serverY..; sprite.x = x; sprite.y = y; sprite.nametag.x = x; sprite.nametag.y = y - 110; I want player to move 300 pixels a second. Is it possible to make it smooth? -- sprite.nametag is a Phaser.Text object. Link to comment Share on other sites More sharing options...
space_elevators Posted May 22, 2017 Share Posted May 22, 2017 Instead of pulling the client sprite position from the server and setting it directly, you might set it as a target and have the sprite handle itself moving to that position. For example, in pseudocode: // server stays the same // client: var targetX = serverX; var targetY = serverY; // have `lerp` functions interpolate between current sprite position and target position, using whatever speed properties the sprite has sprite.x = lerpX(targetX); sprite.y = lerpY(targetY); sprite.nametag.x = sprite.x; sprite.nametag.y = sprite.y - 110; Does that make sense? Link to comment Share on other sites More sharing options...
Tufan Posted May 22, 2017 Author Share Posted May 22, 2017 11 minutes ago, space_elevators said: Instead of pulling the client sprite position from the server and setting it directly, you might set it as a target and have the sprite handle itself moving to that position. I think it wouldn't work that way, in your example client movements might be delayed if server sends new target before sprite reach old target. Link to comment Share on other sites More sharing options...
space_elevators Posted May 22, 2017 Share Posted May 22, 2017 The way I was thinking, targetX and targetY would be constantly changing as a character is moving - you won't wait for the sprite to reach targetX/Y before changing that target. I might be misunderstanding the issue you mentioned, though, and let me know if I am! Tufan 1 Link to comment Share on other sites More sharing options...
Tufan Posted May 22, 2017 Author Share Posted May 22, 2017 43 minutes ago, space_elevators said: The way I was thinking, targetX and targetY would be constantly changing as a character is moving - you won't wait for the sprite to reach targetX/Y before changing that target. I might be misunderstanding the issue you mentioned, though, and let me know if I am! Client and server must have the same X,Y values synchronously. In your way, server wants client to move to specific coordinates but have no idea where the sprite actually is. I'm handling everything on the server (includes collisions), client has one job to do: render game scene. I'm working on a real-time shooter game (like diep.io) so i can't have target X,Y (can i?). I need the exact coordinates of sprite. Link to comment Share on other sites More sharing options...
royibernthal Posted May 23, 2017 Share Posted May 23, 2017 What are you using on your server side and how do your client and server communicate? It sounds like you're limiting the answer to increasing the server <-> client speed, which is not really related to Phaser. Even if you optimize your server <-> client speed, as far as I know space_elevators is right, that's how it's done in multiplayer games. That's why if you have a bad connection players can seem to move around smoothly but many hits won't be taken into account, that's one of the reasons why lag is annoying in multiplayer games. The best solution, again as far as I know, is to interpolate between current position to last known position received from server, based on game-specific logic to make it look as smooth as possible. The faster the server <-> client speed, the less noticeable the interpolation will be, it'll only be noticeable when server <-> client speed is bad, at which point you have no better option but to at least move the players around smoothly to make the lag experience more playable. Naturally whenever you receive a new position from the server it overrides the previous position and the interpolation is recalculated. space_elevators and Tufan 2 Link to comment Share on other sites More sharing options...
Jammy Posted May 23, 2017 Share Posted May 23, 2017 you can't achieve complete synchronicity with the server as there is always a delay, the client must render the move from A to B otherwise a slow connection would mean sprites just dart all over the place. At least with the client rendering the transitions you will only see whats called "rubber banding" https://en.wikipedia.org/wiki/Rubber_banding space_elevators and Tufan 2 Link to comment Share on other sites More sharing options...
Antriel Posted May 23, 2017 Share Posted May 23, 2017 I recommend reading this http://www.gabrielgambetta.com/fpm2.html and other articles you can google about client-side interpolation. Good luck Tufan 1 Link to comment Share on other sites More sharing options...
Tufan Posted May 23, 2017 Author Share Posted May 23, 2017 Way 1: Handling all the movement on the client, sending x,y to the server every 100ms and doing some anticheat things on the server. (like transformice.com do) Way 2: Handling movement on the server, moving entity on the client like space_elevators said. Which way is better and why? Link to comment Share on other sites More sharing options...
Antriel Posted May 24, 2017 Share Posted May 24, 2017 Way 1: It's gonna be very difficult to prevent cheating if the client is authoritative about its state. You could limit some things like teleporting across the map, but it wouldn't be possible to detect things like teleporting a small distance. Way 2: This would definitely make cheating more difficult, at least in regard to movement. But it's more complicated to implement. In the end it depends on the type of the game and what you want to achieve. If the game gets popular, it's bound to have a lot of people trying to cheat – that's one thing to keep in mind. Way 2 will also need stronger server. Personally, I would go for way 2. Cheating can kill a game – that's basically the main reason. I wouldn't implement it in the way @space_elevators said though. That approach would cause visible lag and make the game borderline unplayable. I would use client-side prediction and server reconciliation techniques mentioned in the article in my previous comment. What @space_elevators described is called entity interpolation and is used for entities of other players, not the user's entity/character. Other resources about this topic (though imho more difficult to understand, they do go more deeply into it):Latency Compensating Methods in Client/Server In-game Protocol Design and Optimization by Yahn W. Bernier from Valve.What every programmer needs to know about game networking by Glenn Fiedler.Real Time Multiplayer in HTML5 by Sven Bergström. I would start with this one. It's for HTML5 and Sven explains it really really well. Tufan and space_elevators 2 Link to comment Share on other sites More sharing options...
Raggar Posted May 24, 2017 Share Posted May 24, 2017 You can see the source code: http://www.gabrielgambetta.com/fpm_live.html I'm using this for one of my projects in 3D, and it works very well, even if it's discouraged to do this instead of applying velocities to the physics-bodies. You just have to validate the inputs, as there are still 2 ways to cheat using this: #1: Send bigger deltas. If you're delta is 0.016 and you instead send 0.032, you move double the distance. #2: Send more frequent updates. If you send 0.016 input deltas at 60Hz, you move the correct distance. What happens if you hack the client to send at 120Hz? You move at double speed again. You'll have to cap the number of received movement inputs for each second (+/- some packet loss). You'll have to limit the size of the delta timestamps, so if a client has a lag spike down to, let's say, 20FPS, this will be the absolute maximum size of the deltas, otherwise ignore them. You can combine these two, so that if you receive ~60 inputs per second, the maximum delta timestamp to process will be 0.016. Link to comment Share on other sites More sharing options...
Recommended Posts