Advertisement

movement problems in a 2d action RPG

Started by October 14, 2004 01:54 AM
18 comments, last by hplus0603 20 years, 3 months ago
hi, im working on networking my 2d action / RPG using Rakknet. anyway, i figured i could save bandwith by having movement based on the mouse. e.g., a player clicks somewhere on the map and then his character walks to where he clicked. this way, i only have to send messages about movement everytime the player clicked to move somewhere new (this is where i am, this is where im going). also, i figured i could put a timestamp in this packet as well. when a client receives this packet, he would find which player it was for, then set that players velocity based on the info given. also, i would calculate how long ago it actually happen, and increase velocity based on that to make up for lag. ie, the other players will seem to move faster if you are lagging. is this a bad way to do it? anyway, heres the problem ive encountered. how do you tell the other clients that you've stopped? say you run into a wall or want to stop for some reason, you click a button or something and you stop... but then what? you send a message to everyone saying that you have stopped and where you stopped... but, another client might receive this 300 MS later... so when that client stops you, on his end he will have moved a little further then he really did because of the 300 MS delay to get the "player stopped" message. so when i set the players position, it will appear like hes jumped or jerked back. does anyone know how i could stop this from happening? or maybe another way to do it? my goal is to have around 20 people connected at once when the servers on a cable modem, and like i said its an action / RPG in a futuristic setting (real time combat with guns and stuff). thanks for any help. [Edited by - graveyard filla on October 14, 2004 3:17:10 AM]
FTA, my 2D futuristic action MMORPG
Can you make him walk back towards the correct position? I think this is reasonable because it'll just look like he walked forward and then turned around and walked back for a bit.

-- OR --

How much of your game is based on action? Is it absolutely necessary that players are at the exact positions? If not, let them be a little off if the error is not too big.

-j
Jonathan Makqueasy gamesgate 88[email=jon.mak@utoronto.ca]email[/email]
Advertisement
You could have your game work like in an FPS game where commands are sent to a server and the server returns the world state. In a P2P network topology, someone must become the server as well as maintain its client view; this makes the game unbalanced in favor of the player running the server.

With the many units that interact in a typical RTS/RPG, this will consume a lot of bandwidth. You could implement a turn-based system where specific time slots are pre-allocated for each player (say 100ms apart) and for which commands are issued with a forward timestamp of 2-3 turns ahead of time so that every player has the time to receive the command and acknowledge its reception. Commands that are issued within the said time window will be executed a bit later, but at least all the players will see the same thing. This implies that all players run the very same game simulation and that commands must be certified before being integrated in the simulation. Exchanging only commands reduces the bandwidth requirements a lot!

This is how Age of Empire was designed (see Terrano's article { here } ). Granted, AoE is an RTS, but there are networking concepts in this article that applies in your case. Getting in sync needs special code for this. You can find network synchronization methods and source code { here }.

-cb
Stopping is no different from walking. When you stop, you send "here's where I am, here's where I want to go" and both are the same location. All the other clients will make you walk to that point.

Also, if you walk into a wall, and then stop, presumably you'd walk into the same wall on all the other clients, so there wouldn't be much of a discrepancy anyway.
enum Bool { True, False, FileNotFound };
cbenoi is on the right track. When doing network code the client should only make requests to the server. The server is then responsible for maintaining/updating the world state and issuing authoritative updates to the clients. A client should never be making updates to the world-state itself, save some dead-reckoning and such, or you will end up with out-of-sync clients.

The convo between client and server should go something like this:
CLIENT: Server, I'd like to move to (8,9) please. I'll get a start if I think its ok, but I'll go back if you tell me to(this is reckoning.)
SERVER: Got your request. Sounds good. Your new position is (4, 3)
... other messages ...
SERVER: Your new position is (6, 6).
... other messages ...
SERVER: Theres an impassible object in the way. Your final position is (7, 7).

throw table_exception("(? ???)? ? ???");

> SERVER: Your new position is (6, 6).

Well, it's more like:

CLIENT1: Unit X, walk south now.
SERVER: Unit X, start walking south at time T.
CLIENT1: Unit X movement at time 'T' confirmed.
CLIENT2: Unit X movement at time 'T' confirmed.

Then each client will wait until time 'T' comes and then run the command against the current game state at that time. Collision detection can still be done on clients because both the server and the clients have a copy of the running simulation. You don't need the unit to stop when it hits a wall because that can be computed as part of the simulation on each client.

There are no discrepancies because each client have exactly the same game state and commands are executed in sync. Even the client that has send a command must wait for the server to bounce back the order before scheduling the command for execution at time 'T'. And because each client run the same simulation, cheating can be detected when an issued command doesn't make any sense. You can't tell Unit X to to some task if it already dead, for example.

Again, this is well explained in Terrano's acticle.

-cb
Advertisement
hi everyone. thanks a lot for your replies... i havent replied yet because ive been reading these articles, trying to get this all to sink in. its very complicated you know [smile]. in fact, it seems the more i learn about network programming, the more complicated it gets [smile].

anyway, so from my understanding, it should work like this...

-the client X wants to move, so he clicks on the upper right portion of the screen. he tells the server "i want to go to x,y"

-another client, Y, wants to move, so he clicks the left side of his screen. he tells the server "i want to go to x,y"

-the server reeceives both commands. he also receives all other commands from any other client. he waits untill a certain amount of time has passed, and then he sends out this "pool" of commands back to each client.

-client X gets back a message saying "ok, start moving there". he also gets a message saying "Y wants to move to x,y, too btw".

-client Y gets back a message saying "ok, start moving there". he too gets a message saying "X wants to move to x,y"

both clients move their own and the other guys character.

ok, this is the gist of it? but is this feasible for a mini-MMOG? basically, i want to have an online action / RPG, only with maybe 20-100 people online at most. however, my more realistic goal is 20 people on at once using a cable modem as the server. like they did in AOE, instead of sending the "world update" to everyone at once, i could send it to 5 people at once, wait 100 ms, another 5 people, wait 100 ms.... however, since the game could possible be huge, a lot of people wont care about other people, e.g., one guy is on a completely different side of the world then another, so theres no need to send info about those clients to each other. the solution is to group togeather people who are close to each other (possibly just those who are on the same map?), and then only send out the commands to those who are in the same group. does anyone of this sound right, or am i totally off? my main concern though is, is this a good architecture for my game? keep in mine, it IS an action game too, meaning bullets and grenades and explosions will be flying all over the place during combat, in real time...

theres one thing i still dont understand (and ive read that artcle at least twice, along with a bunch of the codewhore articles [smile]).. when the server sends out this master update, client X might get it 200 MS later, while client Y will get it 300 MS later.. they both execute the commands instantly, so X is 100 ms ahead of Y... what is the solution to this? i realize its time stamping the packets, but how does it work? first of all, im using Rakknet, which has a wonderful feature of synchronizing the clocks on each computer, so that i can timestamp a packet and just do RakNetGetTime() - timestamp to find out how long ago this packet was time-stamped. so, what i was thinking was, before the server sent on this master update, he would time stamp it, so when the client received this update, he knew "player X wanted to go to x,y 200 MS ago". given this, how do i make a smooth transition to his destination, knowing i have to make up for 200 MS of lost time? do i simply just have the character jump 200 MS worth of time, or what?

also, what about the server? im guessing the server should keep track of each client, where he is, what hes doing, where hes moving... when the server sends out this world state message, im guessing the server also applies this message to his own simluation? so when the server sends to player's X and Y "hey guys you have to move these characters to over there", he also will move his versions of X and Y too ? over time, that is, not just at once... also, what about things like collision detection? should the server be doing this also?

thanks a lot everyone for all your help. this stuff isnt THAT complicated. i think i can handle it [smile]. with your guys help, of course.
FTA, my 2D futuristic action MMORPG
sorry to bump this, but i'd really appreciate any help. i have basic movement and chat working, but i don't want to continue much further untill i know how to do it properly. any help is greatly appreciated.

also, the way movement is i use the mouse for movement, and when the player clicks, it sends to the server "there is where i am, this is where im going", and the server bounces this to all other clients and they set velocity and start moving the character.

however, this isnt the way im suposed to be doing it, i dont think.. and im not sure how to synchronize it this way.. thanks for any help.
FTA, my 2D futuristic action MMORPG
That method will work fine for something like an RPG. I think you should keep going with it, and only change it if you have a compelling reason to do so.
enum Bool { True, False, FileNotFound };
hi hplus,

thanks for your reply. i guess i won't be doing it the way it was done in AoE then as i dont fully understand...

ok then, on to my problems. how do i make fixes for lag? that is, lets say im the client (or server even) and get a packet, it says "player 4 is at (x,y), and he clicked at (x,y), at time T"..

now what? i calculate velocity and start moving towards my goal. however, time T says that this *really* happend 200 MS ago. so how do i make up for that time? i could just move at my velocity 200 MS worth of space, however, this makes the movement look jumpy. how can i make it smooth?

also, same goes for projectiles.. i fire my gun, and say "my ID is 3, my gun's ID is 1, im standing at (x,y), my target is at (x,y), and the time is T"... now, i recieve this packet, create the bullet on my local simulation.. but again, how do i make up for the time elapsed since the event truly happend? i could just move the projectile X amount of pixels to make up for time lost, but then this appears like the bullets are being fired slightly in front of the gun, or in bad lag, even a decent distance from the gun. not only that, but what if there was an object in the way, that we just "jumped" over?

my one thoery was to scale everything's velocity to make up for the time passed, so that everything would move faster that was lagged behind. however, this seems like a very bad idea.

i have some more questions though, if you dont mind, it would help me a lot.

lets say a player clicks somewhere on the map, but there is a wall in the way. on the local machine, he will bump into this wall and stop moving. however, on the other clients, he continues on his strait path, walks through the wall, and stops at his destination. his position is corrected when the player clicks somewhere again...

on the client, do i do collision detection for other clients? i figured if i do collision detection of remote clients, this will stop the move through wall thing. but is this a bad idea for any reason?

on the server, do i do collision detection on the clients? again, same problem, when a player clicks and his path is blocked, he will continue moving.. so then i must do collision detection for all clients on the server, also?

-OR-

i suppose i could send a packet "hey i hit a wall at (x,y)". however, this will be slightly lagged behind. so for a moment, the other player might appear to be in a wall.

also, how much logic should the server do? and how much logic should a client do for other clients? depending on how the above questions are answered, this will be my scheme:

-clients only send mouse clicks

-the client takes the click info, calculates velocity, and movement and collision for all other clients

-the server receives the click info, calculates velocity, and does movement and collision for all clients

how does this sound? too much logic? or not?

thanks a lot for any help!

EDIT: i just realized something. for movement, do i really need to say "this is where i am, this is where im going"? can't i just say "this is where im going". i mean, the client / server *should* already know where i am, no? as long as i send my initial position one time... preliminary tests show that im correct, however, i'd like your opinion. actually, i guess sending the "where i am" part will sync things. thanks ALOT again!

[Edited by - graveyard filla on October 24, 2004 6:06:02 PM]
FTA, my 2D futuristic action MMORPG

This topic is closed to new replies.

Advertisement