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.
Related
I am creating a 2d topdown game (with canvas size 720x480) where I want the camera to move once the player reaches a certain part of the screen. For example, once the player reaches 2/3 of the way to the right, the camera should then start scrolling to the right.
For reference, here is an image of the game world: game
In my code, I have every object implementing a "genericObj" class, which has a position, velocity, and dimensions. So this is what I am thinking of doing once the player reaches 2/3 of the way to the right and is continuing to move to the right:
set the player's velocity to half the original
update every object's velocity with the negative of half the player's velocity (object.velocity -= player.velocity)
check if objects are within the view of the camera
display the objects that are within the view, disregard others
The reason for using half the player's velocity for both the new player velocity and the objects is that, in my code, the player movement sprite is only updated when the player is moving. Therefore, I need the player to be moving as opposed to setting the player velocity to 0 and the velocity of every object to negative player.velocity.
Is this a good way of "moving" the camera? What are some better methods of moving the camera? Also, would performance be an issue if I used this method of moving the camera (for example if I had 50+ objects)?
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 am working on a simple 2d multiplayer game with players that have a turret that faces a certain direction (0-360 degrees)
The turret is slow at changing its direction and thus has two values:
heading, which is the direction it is currently facing
desiredHeading, which is the direction it wants to face (player input)
The function moveTurret() is called once per frame and increases/decreases the heading by a certain value, so it matches the desiredHeading after some time. (--> turret moves slowly into desired direction)
Since my client receives updates every X milliseconds via the network, I have a hard time to render those rotations smoothly!
My current approach is as follows:
client periodically receives the heading for each other player
client sets the received values as desiredHeading for the respective players
moveTurret() is called for those players every frame
I thought the client would then approximate the rotation and would smoothly render the turret into its right direction, however this doesn't work at all and the animation is wobbling back and forth.
Does anyone know a simple approach for this problem? I have found some quaternion interpolation and matrix based algorithms, but none seemed to fit for my approach, since I only have a heading-value and my game does not use matrix calculations.
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. :)
This has been greatly bothering me in the past few weeks. In this time I've been researching online, even reading books in the Computers section at Borders to try to find an answer, but I haven't had much luck.
I programmed a 2D level editor for side-scroller video games. Now I want to turn it into a game where I have a player who can run and jump to explore the level, similar to "Mario".
The thing that is really giving me trouble is the collision response (not detection: I already know how to tell if two blocks are colliding). Here are some scenarios that I am going to illustrate so that you can see my problems (the shaded blocks are the ground, the arrow is the velocity vector of the player, the dashed lines are the projected path of the player).
See this collision response scenarios image:
http://dl.dropbox.com/u/12556943/collision_detection.jpg
Assume that the velocity vectors in scenarios (1) and (2) are equal (same direction and magnitude). Yet, in scenario (1), the player is hitting the side of the block, and in scenario (2), the player is landing on top of the block. This allows me to conclude that determining the collision response is dependent not only on the velocity vector of the player, but also the player's relative position to the colliding block. This leads to my first question: knowing the velocity vector and the relative position of the player, how can I determine from which direction (either left side, right side, top, or bottom) the player is colliding with the block?
Another problem that I'm having is how to determine the collision response if the player collides with multiple blocks in the same frame. For instance, assume that in scenario (3), the player collides with both of those blocks at the same time. I'm assuming that I'm going to have to loop through each block that the player is colliding with and adjust the reaction accordingly from each block. To sum it up, this is my second question: how do I handle collision response if the player collides with multiple blocks?
Notice that I never revealed the language that I'm programming in; this is because I'd prefer for you to not know (nothing personal, though :] ). I'm more interested in pseudo-code than to see language-specific code.
Thanks!
I think the way XNA's example platform game handles collisions could work well for you. I posted this answer to a very similar question elsewhere on Stack Overflow but will relay it here as well.
After applying movement, check for and resolve collisions.
Determine the tiles the player overlaps based on the player's bounding box.
Iterate through all of those tiles doing the following: (it's usually not very many unless your player is huge compared to your world tiles)
If the tile being checked isn't passable:
Determine how far on the X and Y axes the player is overlapping the non-passable tile
Resolve collision by moving the player out of that tile only on the shallow axis (whichever axis is least penetrated)
For example, if Y is the shallow axis and the collision is below, shift the player up to no longer overlap that tile.
Something like this: if(abs(overlap.y) < abs(overlap.x)) { position.y += overlap.y; } else { position.x += overlap.x; }
Update the bounding box's position based on the player's new position
Move on to the next tile...
If the tile being checked is passable, do nothing
If it's possible that resolving a collision could move the player into another collision, you may want to run through the above algorithm a second time. Or redesign your level.
The XNA version of this logic is in player.cs in the HandleCollisions() function if you are interested in grabbing their code to see what they specifically do there.
So what makes this a little more tricky is the constant force of gravity adjusting your players position. If your player jumps on top of a block they shouldn't bounce off they should land on top of the block and stay there. However, if the player hits a block on the left or right they shouldn't just stay there gravity must pull them down. I think that's roughly your question at a high level.
I think you'll want to separate the two forces of gravity and player velocity from collision detection/response algorithm. Using the velocity of the player if they collide with a block regardless of direction simply move the player's position to the edge of the collision, and subtract equal and opposite vector from the player's velocity since not doing this would cause them to collide yet again with the object. You will want to calculate the intersection point and place the player's position there on the block.
On a side note you could vary that really big force by what type of block the player collided with allowing for interesting responses like the player can break through the block if they are running fast enough (ie the player's velocity > than the force of the block)
Then continue to apply the constant force gravity to the player's position and continue doing your normal calculation to determine if the player has reached a floor.
I think by separating these two concepts you have a really simple straight forward collision response algorithm, and you have a fairly simple gravity-floor algorithm. That way you can vary gravity without having to redo your collision response algorithm. Say for example a water level, space level, etc and collision detection response is all the same.
I thought about this for a long time recently.
I am using the separating axis theorem, and so if I detected a collision I proceeded to project the object onto the normalized velocity vector and move the object by that distance in the direction of the negative velocity vector. Assuming the object came from a safe place this solution will position the object in a safe place post collision.
May not be the answer you're looking to get, but hopefully it'll point you in the right direction?