Skip to main content
GameDev.net gamedev.net
🔒 Locked

Player Movement

Started by VBStrider Mar 26, 2006 at 1:53 PM 45 replies 8.5k views
Original Post
VBStrider
VBStrider
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
hplus0603
hplus0603
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?
enum Bool { True, False, FileNotFound };
hplus0603
hplus0603
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.
enum Bool { True, False, FileNotFound };
hplus0603
hplus0603
Quote:
What is the destination, and when should it be sent?


The destination is where the player wants to move to (or NPC), and it should be sent in the next available update packet.
enum Bool { True, False, FileNotFound };
graveyard filla
graveyard filla
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.....
FTA, my 2D futuristic action MMORPG
VBStrider
VBStrider
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
graveyard filla
graveyard filla
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...
FTA, my 2D futuristic action MMORPG
graveyard filla
graveyard filla
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....
FTA, my 2D futuristic action MMORPG
graveyard filla
graveyard filla
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".
FTA, my 2D futuristic action MMORPG
VBStrider
VBStrider
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
graveyard filla
graveyard filla
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.
FTA, my 2D futuristic action MMORPG
VBStrider
VBStrider
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
Afr0m@n
Afr0m@n
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]
_______________________Afr0Games
graveyard filla
graveyard filla
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".
FTA, my 2D futuristic action MMORPG
graveyard filla
graveyard filla
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].
FTA, my 2D futuristic action MMORPG

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.