Multiplayer in rpg game

Started by
35 comments, last by bitshit 18 years, 3 months ago
Anonymous & Hplus: thanks, that was the insight I was looking for. I often read statements expirienced people make, which are probably true, but which don't make me understand actually why these statements would be true.

Anonymous:
You hit the nail on the head with your explanation. I don't know if you read my other recent post in this forum, but its actually funny as Im trying to learn how to program multiplayer games by creating a networked version of pong. (With all respect to the topic starter, excuse me for hijacking this thread ;) I see way too many people trying to create a MMOG as an excersise into...well.. about all aspects of programming :) Im trying to focus on the problem of making a single player game I already developed (pong) into a multiplayer game, without having to worry about other too advanced topics like (quantum :p)physics, motion synthesis, global illumination and other stuff that deserves a lifetime of research ;-)

The only thing I find dissapointing about your post I find is that when it gets exciting (at the point where we have one authorative "server" controlling the gamestate but where "our paddle would take 400ms before we saw it respond to our controller input.. Way too sluggish to be playable." is the issue remaining.), no possible solution is given. ;)

Have you deliberatly left that open? For my pong game i came to the solution to have a client/server architecture, have the server run an authorative simulation of the game, have clients predict the trajectory of the balls when no update is available, use the the AI to predict the movement of opponents bats when no update is available and snap back to a corrected state if the server tell us a position update was guessed wrong... I guess even a simple game like Pong wouldn't work with player latency higher than 200ms?
Advertisement
Typically, what you do is to let the player immediately make the move, and hope that the server accepts it when it receives it. If the server doesn't, then a correction needs to be sent back to the client.

Remains to answer what to do when the other end acts on information that's 400 ms old. That's up to game design to decide -- different problems need different solutions. The base problem is that there is latency, so really quick games that depend on low latency game play (say, table tennis, or fighters) may not work at all.
enum Bool { True, False, FileNotFound };
I just came here to read on networking, but that pong example got me thinking.

Keep in mind I dont know crap about this.. :s

Wouldnt the best way to go about it be to send ball initial X,Y and Direction and Velocity to both clients, then the clients locally on their machine calculates the ball movement from thoose variables only, as well as the server?

This way you dont really need to send information to server and back all the time, as long as the ball only moves and doesnt hit anything. Both clients and server knows where the ball is exactly since they all knew its initial x,y, direction and speed and all have the same formulas to make out its position.

The only data client need to send to server is movement.

C1 tells server he moves up, Server tells C2 the location of (C1 - ping) maybe..

If the ball hits something every machine will know it and can localy recalculate the balls movement without exchanging data, checking with the server only now and then that they are on the same location. Else the servers info overwrites the local location ofc (causing lag-feel if that happens).


Erh so much text... was only loose toughts

EDIT : lol see now I only really reposted his stuff in my own words.... damn I must be tired. Sorry ;)
Windows - Dev-Cpp 4.9.9 - SDL - SDL_Net
I deliberately left the question open to show the difficulty involved in finding a workable answer. I will however, give some food for thought. This assumes a peer to peer model with a machine who has been elected as an arbitrator:

In my models I send a global timestamp with my positional updates, so clients can determine how old the update is. (Clients first have to negotiate a common timeframe). Using that information I can predict location, however, I do not actually display the predicted location (i use that location behind the scenes to make decisions) instead i interpolate the samples as i recieve them.

I'd use a concept of a shared object for the ball (one that can change ownership), with a bounding volume around it. The bounding volume's size would fluctuate based on latency. When a paddle intersects the bounding volume, a request is made to gain ownership of the ball (you need a machine that acts as an arbitrator for this process). Whomever owns the ball, sends the updates for it. And whichever paddle the ball is about to collide with (due to the test for the bouding volume), will control the ball.

I usually interpolate position. In this case, the positional interpolation will cause a temporary fluctuation in the speed of the ball proportional to the latency between the clients. But it would look better than a "warp" or jump when the other player takes ownership. This speed fluctuation could even be distributed among the 2 clients by using the timestamp and predicted location to be able to slow the ball down slightly on one player's screen, and speed it up slightly on the other's.

Depending on the latency, this may be very jarring visually, or practically undetectible. It would have to be tested and tweaked.

Ok, so what's happening in your design would be slowing down the ball proportional to the latency. So with much latency, the game would go slowmotion for the client not controlling the ball at that time, while it can go fast at the screen of the client controlling the ball at that moment, is that right?

This would indeed prevent the ball / opponent bat from warping (for the client who's not in control of the ball at that time). The p2p architecture you propose has as positive that updating gamestates could be a bit faster; as there's (probably) a smaller RTT as would be the case with a client/server architecture. But the downside would that its prone to cheating and is less obvious to implement than a client/server model I'd think?
Who is AP? He should definetaly have some ratings! [smile]

After reding all the answers, this seems ever more daunting that I first thought. :S But if I am to take a shot at it, Im going to go with the server/client approach. Just seems simpler.

I dont care if I make something flawless, superb or even good. Im going far beyond expectations if I just reach "working".

But say we have my dungeon. We want the clients to handle the A* to ease the load on the server. But who does the A* for which monster? Who is the "owner"? If I am to use my newly learnt network terminology. :P

As Im thinking every monster on the map that is not visible is going to be totally inactive, it makes sense to make the spotting client owner of the monster. But then the scenario would look like: client sees monster, client gets ownership, calculates behaviour and A* stuff, sends data to server, server sends update data to all the other clients. Then we would have two sets of latency, client -> server, server -> client.

Im not going to have animations, physics or anything. Stuff I want to send are the positions of entities and some small sets of AI behaviour. Am I going to be able to complete this?
The ball would do whatever it took to smoothly approach the assumed position of the new client. this change would hopefully be pretty small.

Peer to peer in general is less secure than client server. At least for clients who aren't the server ;) And the code is a little less straightforward.

But it addresses the latency problem. There is a lot of give and take when determining a network model.

Most games I have developed have been peer to peer, and have allowed for anyone in the game to drop out and the game to continue. This requires a more distributed gamestate than a client/server model. If your server drops out of the game, one of the clients has to be able to take on the responsibility of the old server - and that requires knowledge of the entire gamestate. a shared object peer to peer model works very well in this instance (obviously it's not a concern in a 2 player game, but I think you can see the point)

It's all give and take, and trying to find a good balance. There are many different solutions to the problem, all with different pros and cons.



Miz:

Sorry to have gone on a tangent, I'll address your concerns:

If you are going client server, you really should have the server control everying (including player movement believe it or not) The server is the only machine that will know the complete gamestate. You really lose the benefits of a client server model if you start having the clients taking control of stuff.

I assume you don't have any physics based gameplay going on, so you don't really need to do anything too complex.

Because the server knows the complete gamestate, he is more appropriate to take control of all of the pathfinding.

The flow would go somewhat like this:

1. player sends his input to the server (timestamped using a global time)
2. player begins to move local avatar
3. server recieves input packet from player and moves him on the server based on input

(on most FPS shooters, input queues are kept for all the players. when new input is recieved, it is placed in the queue at the correct time, and the server goes back to the gamestate at the time the player's packet was sent. It then runs the simulation forward from that time with the newly recieved input. This basically "inserts" the event into the past, to recalculate the current gamestate. This is probably way more complicated than you need to worry about right now, but wanted to give you an idea of how it is done)

4. server sends position and any resulting events back to player
5. player recieves definitive position from server, and interpolates to a predicted position based on the server's response.


It's important to note this is for movement only,

events such as attacks are usually done without any rollback of gamestate.

1. player requestst to fire
2. server gets request and simulates event
3. server tells client that the event occured
4. client allows attack to happen

(This is why, on some really latent connections in FPS games, there is a delay actually firing your weapon)

So basically, the client sends the the state of the keyboard and mouse to the server, and in return get the current state of the gameworld?

And along with every input or datapackage sent to the server, there is a timestamp. When the server checks the timestamp it sees that this was in fact 150 ticks ago, and the player is allowed to take a step every 50 tick, so it takes three steps instead of one? is that the general idea?

But what about timestamp from the server? If the server is controlling everything, we cant really simulate movement. So the stuff we see on screen is what happened at the server 200 ms ago or something, then you could end up being killed by a monster some distance away from you? Since the monster could have walked closer and attack while the client was waiting for data.

Ill head to the article section and see if they got anything about this.

I thought that maybe I should try to complete all the other aspects of the game first... but seing how the networking stuff spreads over absolutely every area of the game... maybe its better not to wait.

This topic is closed to new replies.

Advertisement