Sign in to follow this  
VBStrider

Player Movement

Recommended Posts

VBStrider    303
What is the best method for handling player movement in a client-server 2D tile based real-time game? I know about dead reckoning, but that is only part of it (and the only thing I was able to find info about when I searched the forums). VBStrider

Share this post


Link to post
Share on other sites
hplus0603    11347
What is special about tile-based? Do you move only onto "whole" tiles (a la strategy games) such that you can't be "between" tiles? If you send positions to clients, and use some form of interpolation or dead reckoning, what part of that doesn't work for you?

Share this post


Link to post
Share on other sites
VBStrider    303
Yes, players cannot be between two tiles.

I have attempted writing this myself, but the system did not work out (players jumped too much). Which is why I'm asking what the best system to use is.

VBStrider

Share this post


Link to post
Share on other sites
hplus0603    11347
Well, if the player can't be between tiles, then the player needs to jump between tiles.

What I would do is send the destination tile, and then have each client run path-finding for the player from the source to the destination. Move the player along at some pre-determined walk/run speed (i e, one square every 0.5 seconds or whatever) along this path-found path.

Share this post


Link to post
Share on other sites
VBStrider    303
There is no jumping as far as the server is concerned. It sees positions as tile positions, not pixel positions.

What is the destination, and when should it be sent?

VBStrider

Share this post


Link to post
Share on other sites
this is how i handle it in my 2d tile based MMORPG. in my game though you aren't limited to moving from tile to tile. since that is how yours is, it should simplify things a lot.

FWIW, this is how i handle it though:


- when the user presses an arrow key, he sends to the server "i want my direction to be X"

- server gets this, starts moving on his simulation, then tells the player and everyone else whos important "player X is moving in direction Y"

- when the user releases the arrow key, he sends to the server "i want to stop"
- server gets this, stops the player on his simulation, and then tells the player and everyone else "player X has stopped"


If you handle it like this, you will only have to send a packet when the player changes directions...... this means if they are moving for long distances in a single direction, you will never have to send any movement packets...... seems like that sort of thing might be common in a 2d RPG, you might want to keep that in mind. of course, this might not work for you depending on how you partition your world network wise.....

Share this post


Link to post
Share on other sites
VBStrider    303
graveyard filla, that is the system I am currently using. However, players get out of sync slightly and when the stop packet is received, the player is jumped to that location. This causes players to appear to jerk around while moving.

VBStrider

Share this post


Link to post
Share on other sites
why are they getting out of sync?

make sure you are doing it exactly like this:


-player pushes arrow key but does NOT move yet, only sends "request to move" packet
-server gets this message, validates, starts moving the player on HIS simulation, and then sends back to the player + all players who are important "player X is starting to move"
-the player who requested to move, as well as the other players in his area get the message. then they start moving that player on their simulation






if you do it like this, you should be in perfect sync. the server is running the "live" simulation, and all the clients are watching a slightly delayed version of this simulation - however they are all watching the same exact thing, just at different times. you basically sacrifice response time to have this perfect sync, but in a 2d MMORPG it is perfectly acceptable. in fact, my game is heavily action based (you can aim and shoot in 360 degrees, real time) and I still find the movement delay perfectly acceptable. you can even start getting more complicated with prediction and interpolation to makes things appear even smoother...

Share this post


Link to post
Share on other sites
VBStrider    303
If I do it that way, there will be a delay between pressing a movement key and actually moving. I do not want this to happen, because it ruins the game.

VBStrider

Share this post


Link to post
Share on other sites
then you have several options, and most will leave you vulnerable to movement hacks, and all will be a lot more complicated to code [grin].

you can start moving on the players simulation, and send a timestamp. in this case, the server and all other clients are playing "catch up" with other players movements. this means you start moving as soon as you press a key, but other players will have a slightly longer delay. this also leaves you vulnerable to a false timestamp. you will also have to code in interpolation because otherwise other players would appear to "jump" slightly.

you do something in between these scenarios. you can go with the scenario i originally posted, that has delayed movement, except you have the player start moving at some point in time after they send the movement request, somewhere around ping/2 MS after. then, by the time they get the ack, they should be in the same position as they are on the server, or close.

you could totally throw away the concept we are talking about now, and go for a more 3d or action based approach - that would be having constant position / update packets be sent at intervals, and you try your best to keep everything in sync.

I have tried many, many different scenarios. I have honestly found the best way is the way I described originally - however that was for my game. Your game might be different....

Share this post


Link to post
Share on other sites
i have no idea, but my best bet would be that Diablo used a system similar to what hplus is describing to you for you to use. IIRC, diablo was pathfinding based - they probably took advantage of this.

are you going for mouse movement? if so, that can GREATLY simplify things. with mouse movement, you only need to send "this is where i clicked" to the server, and, if you want instant movement, you send "this is where i clicked, and the time is T".

Share this post


Link to post
Share on other sites
VBStrider    303
Hmmm, I might just go ahead and use the mouse for movement then. A question about such a system though; when moving in a direction via holding the mouse button down, should the movement destination packet be sent continuously?

VBStrider

Share this post


Link to post
Share on other sites
you would want to put a delay on how often the client can send a "request to move"..... basically make it so when they hold down the mouse, only every Xms a "request to move" packet is sent.....

you'd be surprised at how much of a delay you can put on this before it got annoying... you want to make this delay as big as possible if you want your game to scale well, because chances are everyone is going to always hold down the mouse..... thats how i play at least.....

can you give more details on your game? if your character can move in 360 degrees, then this will use more bandwith..... if you only allow them to move in 8 directions, you can get away with doing what we talked about earlier, when they hold down the mouse only send a packet when they change directions (velocity). i suppose you could do that anyway, but in 360 degree movement it wont be common to stay in the same exact angle for long....

i also want to point out one thing...... IMO you should start with a solid, secure base (e.g. no timestamp sent) and then you add smoke and mirrors on the client side to give the illusion that you start moving immediately after you click..... if you get some good interpolation working you would be surprised at how good you can make the delay look..... just dont forget anything you leave open to vulnerability can and will be hacked.

Share this post


Link to post
Share on other sites
VBStrider    303
If I go with mouse movement, I will probably allow 8 directions (N, NE, E, SE, S, SW, W, NW). If I go with movement via the arrow keys, it's definitely going to be 4 directions (N, E, S, W).

The game is top-down, split up into maps that are 256x256 tiles large. Tiles are 32x32 pixels in size.

Using pathfinding is not a problem, as I already have it implemented.

Events, such as a player moving, attacking, casting a spell, etc. are only sent to the players in the source player's area (a few tiles larger then the player's screen). This cuts down on network traffic at the price of a slight speed hit.

I hope that is enough information :). Thanks for your help so far.

VBStrider

Share this post


Link to post
Share on other sites
Afr0m@n    100
Quote:
Original post by graveyard filla
why are they getting out of sync?

make sure you are doing it exactly like this:

*** Source Snippet Removed ***

if you do it like this, you should be in perfect sync. the server is running the "live" simulation, and all the clients are watching a slightly delayed version of this simulation - however they are all watching the same exact thing, just at different times. you basically sacrifice response time to have this perfect sync, but in a 2d MMORPG it is perfectly acceptable. in fact, my game is heavily action based (you can aim and shoot in 360 degrees, real time) and I still find the movement delay perfectly acceptable. you can even start getting more complicated with prediction and interpolation to makes things appear even smoother...


Why do you even need a live simulation? IMHO, the position packets approach is much simpler. Of course, it comes at a cost of using more bandwidth, but that's only a slight overhead if you interpolate. In addition to that, with the approach I'm taking, each client runs it's own simulation of the game. The only thing that will (eventually) be cached are quests, to avoid players being able to change the quests at will. Apart from that, all the server is used for is updating data between clients. When it comes to movement hacks, that can be prevented using a simple check to make sure that the incoming movement packet from a client isn't larger than the most recent movement packet * a margin.

Edit: Yes, obviously it's easy to say that a good reason for doing simulations on a server is to make sure that things don't get out of sync. However, most MMORPGs basically sync themselves if coded correctly.

Scenario:

A lvl 60 and a lvl 20 is working together taking down a lvl 30 monster. Unless the latency is extremely horrifyingly almost unrealistically large, one of two things will happen: Both of them will die, or the lvl 60 finishes first, sends a packet indicating that he's the winner, and the lvl 20 will not be able to loot.

[Edited by - Afr0m@n on March 28, 2006 6:34:23 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Quote:
Original post by Afr0m@n
Apart from that, all the server is used for is updating data between clients. When it comes to movement hacks, that can be prevented using a simple check to make sure that the incoming movement packet from a client isn't larger than the most recent movement packet * a margin.

Yeah, that will work. Until someone sends a movement vector straight up into the sky, with walking speed. Or are you going to be checking collisions on the server aswell as relaying data between clients?


Share this post


Link to post
Share on other sites
Quote:
Original post by Afr0m@n
When it comes to movement hacks, that can be prevented using a simple check to make sure that the incoming movement packet from a client isn't larger than the most recent movement packet * a margin.


then you will still have movement hacks in your game which will abuse your code "to the margin".

in many cases, even a "small margin" added up over time can cause super-fast movement on a hackers machine. just think about what would happen if the hacker was constantly flooding "movement request" packets and his position was constantly off by exactly your "margin".

Share this post


Link to post
Share on other sites
actually, afroman, i am kind of confused now [grin].

are you talking about a 2d game like we are in this thread? if so, then it shouldn't be a big deal at all for the server to do collision detection, physics, etc, (and run a true, full simulation). i have no experience w/ 3d, but in 2D i have done the math and i could handle hundreds of players fairly easily on my cable connection. CPU usage is not an issue at all.

of course you still want to run the same simulation on the client as well, so everything goes smoother. just have the server send the client the "true" data when you send back acks. then you try to throw around "smoke and mirrors" when the client and server go out of sync. for example, in my game the server tells the client his position everytime he requests a movement, so if the client is out of sync with the server, he will "jump" to the correct position. the smoke and mirrors would be some interpolation code to have him smoothly move to his real position. another example might be when a bullet hits a wall on the client but hits the player on the server - here you could have the client display a blood squirt and some health disapear when it gets the ack from the server, even if the client saw the bullet hit the wall...

the point is though to run the simulation on both ends, but have all client->server interaction work in a request->response way. in the request, the client should not send any data outside of user input, unless it is something you don't care about being hacked. when the server sends a response, he should also send the "correct" data for whatever is going on - the damage done to a player, or the position of a player, etc. most of the time the client and servers data will match perfectly if you do things right. this makes sure that these functions in the game are unhackable and totally clean.

hell, you could even just not send corrections. then hackers would think they are cheating at first, but would get confused and lost really quick [grin]. however in this case you would be hurting the non cheaters in case the simulation DOES go out of sync.

Quote:

When it comes to movement hacks, that can be prevented using a simple check to make sure that the incoming movement packet from a client isn't larger than the most recent movement packet * a margin.


could you please explain a little more how this works? it seems interesting you wouldn't want to run the simulation on the server, and i can't figure out how this could be secure [grin].

Share this post


Link to post
Share on other sites
Afr0m@n    100
Yes, I could explain very much!

Let's say the hackers aren't allowed to cheat more length than 100 ints in all directions (X, Y, (Z)). Then the check on the server would look something like this:

if(MovementPacket.X > LastMovementPacket.X * 100)
{
//Ignore packet
}


Also, to save bandwidth, the packets should be sent about every 500ms and then the rest should be interpolation.

@Anonymous Poster: What has collision detection got to do with anything? You don't even need to have walking speed. If you need walking speed, simply increase the amount with which you update the player's coordinates and make sure it doesn't go over the server's limit.

Now you might go; "Aha! Gotcha! That will allow players to constantly move fast!"

But alas; Simply use a high precision timer on the server, and make sure that the time that a player has used movement speed always is less than the cooldown time of whatever spell gives improved movement speed minus (-) the allowed time.

Share this post


Link to post
Share on other sites
Quote:
Original post by graveyard filla
in many cases, even a "small margin" added up over time can cause super-fast movement on a hackers machine. just think about what would happen if the hacker was constantly flooding "movement request" packets and his position was constantly off by exactly your "margin".

This is quite easy to check. If a player tells the server he needs to move 20 units over the last quarter of a second, but his movement speed is 50 units per second (15 per quarter-second) then obviously the server should only move him 15 units. It's really easy for the server to see if an action is legal or not.

Similarly, there's nothing wrong with client-sent timestamps. If the client spawns into the game at time 0, tells the server he starts moving at time 5 (and the server gets this message at time T >= 5), then tells the server he stopped moving at time 10 (and server time >= 10) then fine. And if he then tells the server he fired a fireball at time 9, the server ignores that time since he already processed a time-10 command, so he has the player fire a fireball at time 11 or whenever he can. As long as the server executes commands in the order it gets them, not retroactively, there aren't any meaningful hacker vulnerabilities that I can see.

Share this post


Link to post
Share on other sites
Quote:
Original post by CGameProgrammer
This is quite easy to check. If a player tells the server he needs to move 20 units over the last quarter of a second, but his movement speed is 50 units per second (15 per quarter-second) then obviously the server should only move him 15 units. It's really easy for the server to see if an action is legal or not.


but how do you handle collision detection? this might keep speed hacks away, but what about walking through walls and such? if the client is telling the server his position, and the server does no physics or checks, whats stopping me from moving through walls?


Quote:

Similarly, there's nothing wrong with client-sent timestamps. If the client spawns into the game at time 0, tells the server he starts moving at time 5 (and the server gets this message at time T >= 5), then tells the server he stopped moving at time 10 (and server time >= 10) then fine. And if he then tells the server he fired a fireball at time 9, the server ignores that time since he already processed a time-10 command, so he has the player fire a fireball at time 11 or whenever he can. As long as the server executes commands in the order it gets them, not retroactively, there aren't any meaningful hacker vulnerabilities that I can see.


the problem isn't sending timestamps that are too "new". the problem is sending ones that are too old. for example, you click and send to the server "i clicked on X,Y and the time is T". now the client starts moving immediately. the server gets this, looks at T, and then "jumps" the client on his simulation to the correct position based on the time. if the client spoofed his timestamp, and makes it smaller (makes it happen longer ago) he could give himself a big "jump". then you have to factor in how often they are allowed to move, so they could possibly be constantly jumping, giving them super fast movement. Ultima Online and Asherons Call, and possibly other commercial MMORPGs all suffered from speedhacks, and I would bet my life it was because of spoofed timestamps.

Share this post


Link to post
Share on other sites
Afr0m@n    100
Quote:
Original post by graveyard filla
Quote:
Original post by CGameProgrammer
This is quite easy to check. If a player tells the server he needs to move 20 units over the last quarter of a second, but his movement speed is 50 units per second (15 per quarter-second) then obviously the server should only move him 15 units. It's really easy for the server to see if an action is legal or not.


but how do you handle collision detection? this might keep speed hacks away, but what about walking through walls and such? if the client is telling the server his position, and the server does no physics or checks, whats stopping me from moving through walls?



Client side collision detection?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this