I’m developing a multiplayer network pong game, my first game ever. The current state is, I’ve running the physic engine with the same configurations on the server and the clients. The own paddle movement is predicted and get just confirmed by the authoritative server. Is a difference detected between them, I correct the position at the client by interpolation. The opponent paddle is also interpolated 200ms to 100ms in the past, because the server is broadcasting snapshots every 100ms to each client.
So far it works very well, but now I have to simulate the ball and have a problem to understanding the procedure.
I’ve read Valve’s (and many other) articles about fast-paced multiplayer several times and understood their approach. Maybe I can compare my ball with their bullets, but their advantage is, the bullets are not visible. When I have to display the ball, and see my paddle in the present, the opponent in the past and the server is somewhere between it, how can I synchronize the ball over all instances and ensure, that the it got ever hit by the paddle even if the paddle is fast moving? Currently my ball’s position is simply set by a server update, so it can happen, that the ball bounces back, even if the paddle is some pixel away (because of a delayed server position).
Until now I’ve got no synced clock over all instances. I’m sending a client step index with each update to the server. If the server did his job, he sends the snapshot with the last step index of each client back to the clients. Now I’m looking for the stored position at the returned step index and compare them. Do I need a common clock to sync the ball?
EDIT:
I've tried to sync a common clock for the server and all clients with a timestamp. But I think it's better to use an own stepping instead of a timestamp (so I don't need to calculate with the ping and so on - and the timestamp will never be exact). The physics are running 60 times per second and now I use this for keeping them synchronized. Is that a good way?
When the ball gets calculated by each client, the angle after bouncing can differ because of the different position of the paddles (the opponent is 200ms in the past). When the server is sending his ball position, velocity and angle (because he knows the position of each paddle and is authoritative), the ball could be in a very different position because of the different angles after bouncing (because the clients receive the server data after 100ms). How is it possible to interpolate such a huge difference?
As you are developing your first game, I think you should try the simplest but brute-force method first. Then you will experience the first exciting result, then you will get courage and try the better methods.
Like Source Engine method, process the game play in one side and send every object state to the other for each 1/30 second. This is a brute method but it works in LAN environment.
Now you will find problems that occur WAN environment where latency is more than 1/30 second.
I am not sure it works actually, but I think that:
Assume that the movement of ball does not change by only player's hit.
Send ball position P, velocity and player A position only when player hits the ball to B.
At B, receive it but process it as if time L is already passed (L=latency between A and B * 2) However, rendered ball should be keep its previous movement until it reaches the ball position P.
Values which never are affected can be masqueraded, even if it is time value. :)
Related
I would like to build from scratch a kind of small (extremely small and simple) MMORPG game with click movements inside a given grid (something like an online Pokemon game). When I click on a cell, the player will move to reach the pointed area (using a pathfinding algorithm such as A*). But, I have no idea about how to build the network protocol of the movement system. And, googling the subject doesn't seem to help me a lot. I need to make a choice: - either I send a message to the server each time I move from one cell to another (which isn't efficient at all because if we are in a 100ms latency network, I can only sens 10movements/sec and if I ask the server to acknowledge the movement it can only do 5moves/sec) - either I send a message each time the player wants to change its direction (it clicks on another cell). The client sends periodically its position to the server and it checks if it's coherent with the destination.
The second solution looks a lot better than the first one and I think that a real game systems must implement that strategy. Am I wrong?
Also, how can we build systems based on that solution that doesn't let a modified (hacked) client be able to send fake positions and teleport anywhere they want? Does real systems implement somethink like a "incoherent sent position" system that will try to try to detect and fix those problems?
Or, is there something simpler to implement? Thank you very much
In a realtime game I would create a panthing mechanic. I would use a formula such as: Speed * time = distance.
now if you run the same logic in the client and the server you only need to send the movement logic at the beginning and the sever can answer with a finish message when the distance is traveled. (compare at the end to prevent cheating. the server always wins)
Now if the client cancels in the movement to go somewhere else, you send a cancelation of panthing and the time that you traveled. The same goes when changing the panthing (in this case you send a new path staring at a new time and place).
Thanks to ScarletMerlin's answers I think there's a simple solution to my problem.
When the player wants to move from one position (for instance 0,0) to another (for instance 10,10), it sends a "MOVE 10 10" message to the server.
Then, only the server will apply the pathfinding algorithm and send after each move the position to the client. (for instance, by message CURRENTLY_ON X Y). Then, the client will update the position of the player.
It's a kind of automatic synchronisation from the server to the client. It also solves the problem of the first solution (one move and one ACK per movement) thanks to pipeling. For instance, if the network has a 1000ms delay and a move is set 50ms, we will just receive messages at time 1000, 1050, 1100, 1150, ... So, we will just feel the lag when the player is changing its direction.
The user will also feel some lag when changing from one direction to another but if we assume that the delay is quite low and symetric (it doesn't seems to be a too strong assumption), it won't be so much percepted (as the change direction will often arrive before the sending of the CURRENTLY_ON message and the server can interrupt its current action (going straight on) to handle the new one).
I'm working on a small multiplayer 2D XNA Game using TCP. My issue is that when more than 2 people connect everyone starts to lag out. Currently for every new x,y position the player has it sends it as a packet to the server to broadacast to every other player connected on the network. This ultimately sends a massive amount of packets which I think causes the issue I'm having.
Is it normal to send every x,y coordinate to every player or am I doing something wrong?
Instead of sending every packet, you should only send packets when the player changes direction, by either jumping, or moving left/right. The clients should handle gravity and collision as normal, while the server validates it.
When they move, send a packet containing:
Their movement vector (This should be a small Vector2 or Point that is either -1, 0, or 1 on each axis. -1 X means they are moving left, 0 means no movement, and 1 means right movement)
You should implement this client side already if you have not (Don't just add X to the velocity when you move, assign it to a movement variable to use later.
Ex:
if (KeyState.IsKeyDown(Keys.Left) { Movement.X = -1 }
...
Velocity += Movement * Speed
Their current position. Send the players current position (The serverside and validated one) to all other players, to make sure their position matches (It may be off due to small changes)
Their current velocity. The velocity of the player should have changed when the movement changed, since they are now going a different direction. Send the velocity along with the position.
Overall, only when a player moves (Ex: Stops holding the left key or presses the jump key) and NOT every frame, send the movement (Direction you are going based on keyboard input), position, and velocity.
Once you have this completed, you may want to add interpolation, which will smooth the movements between updates and make it look less jerky.
I am working on a unity mobile game. Which is like a multiplayer version of temple run. Because this game is meant for mobile there is a fluctuating latency generally in the range of 200ms - 500ms.
Since the path is predetermined and actions the user can perform are limited (jump,slide, use powerup etc) , the remote player keep running on the path until it receives the updated state from its local player.
This strategy generally works pretty well since I only need to send limited amount of data over the network but there is a specific case in which I am having issues.
In the game, players die on the specific positions (obstacles).
I want remote players to die on the same obstacle/position as local player but due to latency in sending message, the remote player crosses the obstacle by the time it receives the death message.
Is there a way to sync the players on the deaths.
One of the things I tried was moving the remote player back to the local players death position but not only does it look awkward visually but can also raise other syncing issues.
Is there some other better way to do this ?
One way I may recommend is to make one player acts like server (not real server). The server-player will do all the computation like moving, jumping, creating scenes, etc. Then the server-player will send all the data to sync with the client-player. The client-player get the data and process game state. The client-player can also send his action (left-right-jump-slide) to the server-player. This way both player will have the same state of the game like position, die. You also need to deal with latency by adding some prediction.
So the solution I implemented was I spawned all the remote player behind enough so they can have some time to receive the information that local player was died on specific obstacle. And in the end there is a straight path where I just sync players again. So that result is displayed correctly.
I try to found the best method to do this, considering a turn by turn cross-plateform game on mobile (3G bandwidth) with projectile and falling blocks.
I wonder if one device (the current player turn = server role) can run the physics and send some "key frames" data (position, orientation of blocks) to the other device, which just interpolate from the current state to the "keyframes" received.
With this method I'm quite afraid about the huge amount of data to guarantee the same visual on the other player's device.
Another method should be to send the physics data (force, acceleration ...) and run physics on the other device too, but I'm afraid to never have the same result at all.
My current implementation works like this:
Server manages physics simulation
On any major collision of any object, the object's absolute position, rotation, AND velocity/acceleration/forces are sent to each client.
Client sets each object at the position along with their velocity and applies the necessary forces.
Client calculates latency and advances the physics system to accommodate for the lag time by that amount.
This, for me, works quite well. I have the physics system running over dozens of sub-systems (maps).
Some key things about my implementation:
Completely ignore any object that isn't flagged as "necessary". For instance, dirt and dust particles that respond to player movement or grass and water as it responds to player movement. Basically non-essential stuff.
All of this is sent through UDP by the way. This would be horrendous on TCP.
You will want to send absolute positions and rotations.
You're right, that if you send just forces, it won't work. It's possible to make this work, but it's much harder than just sending positions. You need both devices to do their calculations the same way, so before each frame, you need to wait for the input from the other device, you need to use the same time step, scripts need to either run in the same order or be commutative, and you can only use CPU instructions guaranteed to give the same result on both machines.
that last one is one that makes it particularly problematic, because it means you can't use floating-point numbers (floats/singles, or doubles). you have to use integers, or roll your own number format, so you can't take advantage of many existing tools.
Many games use a client-server model with client-side prediction. if your game is turn based, you might be able to get away with not using client-side prediction. instead, you could have the client lag behind by some amount of time, so that you can be fairly sure that the server's input will already be there when you go to render. client-side prediction is only important if the client can make changes that the server cares about (such as moving).
i am developing a multiplayer roleplaying game, (No, its not a mmorpg. ;)
My current setup is like this.
Client tells the server "I want to move forward"/"I want to move backwards", the server then updates your entity, and informs all clients in the area about the change. The server is also updating each entity every 20ms and sending updates every 100ms to the clients, these updates contains position, velocity, rotation etc.
So far so good, however i have nothing in store for smoothing the movement between the packets on the client side, and i must say, i can not get it working. I have been reading up on prediction, interpolation, deadreackoning but its all a big mess for me.
So right now i am just doing something like "Position = Packet.Position", which causes a very stuttering movement.
So, what i want help with is, how do i get a more smooth movement? Have been looking at the XNA Prediction Sample, but i could not get it right.
Thanks //F
Read Valve's description of their multiplayer protocol. It should be instructive, and gives a very clear example on how you do the prediction/interpolation.
I'd suggest the idea from another question (see the accepted answer)
Here the client calculates its position itself as if its not a network game. Client regularly sends his current position to the server. And if client cheats or can't continue moving in the chosen direction, server just sends the client his correct position.
The same algorithm was used in Ultima Online (at least when I was playing it 10 years ago)
I solved it by running a ghost entity alongside with my main one.
The ghost will get updated every frame aswell, but whenever a packet comes in, his values are set to the values of the packet.
I then gradually tweak the real entity to where the ghost is.