Beginner Needs Advice

Started by
9 comments, last by mattius 16 years, 11 months ago
Hi, I've just began working on my first MMORPG server and wondered if you experienced guys could offer some advice on best practices. Firstly I will lay out my plan: * Each client sends their position / orientation (if changed since last send) to server every 100 - 250ms (not decided a set rate yet) * Every server tick (100 - 250ms or so) the server sends out the position / orientation of nearby clients /objects to the affected clients only and only if the position / orientation was updated since the last server tick * Each client receives new client data and updates appropriate game objects, using interpolation to smooth movements * If an interaction between one or more clients takes place during any point in the game (e.g. attack, trade etc) then the interaction + affected clients are sent to the server, which then applies server interaction logic and distributes the results to the affected clients (this is not done on server tick, instead it is sent back to the clients as soon as it occurs). Thanks for any advice Mat
Advertisement
You *never* trust the client. This means that the client sends keystrokes only. The server moves and updates the position of the unit and tells the client where the unit is. Meanwhile the client simulates the movement so as to avoid long latency from the client's perspective. You generally also (in an MMO) make the client tolerant of minor differences in position and orientation: i.e. the client won't snap you to the "actual" position if it's within 5 meters or so of where the client currently has you (this prevents rubberbanding).

Similarly with trades and such you *never* trust the client. The client will send to the server "give X to Y person". The server will then verify that X actually exists in the player's bag, that Y is in range, that Y has inventory space, etc before making the trade happen.

Once again *never* trust the client. You should never ever have the client telling the server what it's doing. It will only ever tell the server what it *wants* to do; the server decides first if that's possible before letting the client do anything.

-me
Ok, so applying your comnents I have the following:

* Each client sends a list of their key presses that occured over the last 100 - 250ms to the server
* Every server tick, the server applies the key presses to the server side players, performs any interactions and then sends positional / orientation / damage information etc back to the clients

This seems a much simpler and more secure (which is good), but I cant help being concerned about the load placed on the server
Keypresses are redundant. Server dealing with various key-mappings, different keyboards, different controllers....

You send actions. How these actions come to be is irrelevant, but they contain all the information needed to perform them.

For example:
Attack: ( PlayerID, TargetID, client timestamp, combat turn, special attack ID)
Trade Offer Item: ( PlayerID, TargetID, Item Id, flag:(offered/removed), item quantity)

and so on...

Each of these describes the action completely, and can be easily validated. With key presses, mouse events and other UI-related stuff you get way too many problems, not to mention incredibly annoying lag.

This aproach also allows for easy classification and routing of incoming messages, and dispatching of outgoing.
You can predict how much bandwidth will be consumed, depending on your worst case scenario. How many players, how many NPCs... For true MMORPGs, the bandwidth requirements on the server should be quite massive. How do you plan on running servers? Will you be running 'instances' of cooperative games (Guild Wars, Diablo), or large scale worlds with 100's of players interacting (WoW)?

Also, what about the player accounts, transactions, database, secured connections, ect... This is not easy work.

For MMORPG gaming, if it's point and click and command / event driven, you can just forward commands/events from the server, that should reduce the bandwidth usage. You can also run it through TCP sockets if the rate of commands is slow enough, or write your own reliable protocol and run through UDP. That will make the client run into lockstep (waiting for server commands/events). For TCP, run the socket into a separate thread so you don't lock up the client.

You can run a mix of TCP / UDP transactions, but then it can get messy. If you send comment and do not run prediction on the clients, will the lag in the commands be acceptable? That is usually a no-no for fast games, but can be acceptable for slower games (RPGs).

if you never used sockets, have a look at Beej's tutorials
http://beej.us/guide/bgnet/

if it's fast paced, look at Gaffer's articles and UDP communication
http://www.gaffer.org/archives/zen-of-networked-physics

You can have a look at third party libraries, like RakNet to get the low-level work done for you, or inspiration.

Everything is better with Metal.

Quote:Original post by Antheus
Keypresses are redundant. Server dealing with various key-mappings, different keyboards, different controllers....

You send actions. How these actions come to be is irrelevant, but they contain all the information needed to perform them.

For example:
Attack: ( PlayerID, TargetID, client timestamp, combat turn, special attack ID)
Trade Offer Item: ( PlayerID, TargetID, Item Id, flag:(offered/removed), item quantity)

and so on...

Each of these describes the action completely, and can be easily validated. With key presses, mouse events and other UI-related stuff you get way too many problems, not to mention incredibly annoying lag.

This aproach also allows for easy classification and routing of incoming messages, and dispatching of outgoing.



Yep, I currently convert key strokes to commands such as run forwards, turn left, attack 1, attack 2 etc. Not done the same for mouse events yet though, so I will make a note of that
There are all kinds of fun problems that pop up with this design.

For example, if you send updates only when entities are within scope, and an entity goes from within scope to out of scope, you'll stop sending updates -- but is the client to treat this as "out of scope," or as "is just doing nothing, still at its last position"? One solution is to explicitly manage scope to the client, telling it about out-of-scope events.

Another problem is that of physics; if players block the passage of other players, you will have all kinds of rubber banding and lag with a naive implementation.

However, it's a good start, especially if you're just doing it to learn and/or for fun. Don't let the problems dissuade you! I'm glad you're talking about what you're doing, rather than how great it will be when you're done -- because it won't :-) Talking about what you're doing is always allowed (within limits of decorum, of course).

enum Bool { True, False, FileNotFound };
Quote:Original post by oliii
You can predict how much bandwidth will be consumed, depending on your worst case scenario. How many players, how many NPCs... For true MMORPGs, the bandwidth requirements on the server should be quite massive. How do you plan on running servers? Will you be running 'instances' of cooperative games (Guild Wars, Diablo), or large scale worlds with 100's of players interacting (WoW)?

Also, what about the player accounts, transactions, database, secured connections, ect... This is not easy work.

For MMORPG gaming, if it's point and click and command / event driven, you can just forward commands/events from the server, that should reduce the bandwidth usage. You can also run it through TCP sockets if the rate of commands is slow enough, or write your own reliable protocol and run through UDP. That will make the client run into lockstep (waiting for server commands/events). For TCP, run the socket into a separate thread so you don't lock up the client.

You can run a mix of TCP / UDP transactions, but then it can get messy. If you send comment and do not run prediction on the clients, will the lag in the commands be acceptable? That is usually a no-no for fast games, but can be acceptable for slower games (RPGs).

if you never used sockets, have a look at Beej's tutorials
http://beej.us/guide/bgnet/

if it's fast paced, look at Gaffer's articles and UDP communication
http://www.gaffer.org/archives/zen-of-networked-physics

You can have a look at third party libraries, like RakNet to get the low-level work done for you, or inspiration.


We were thinking along the lines of WoW type roam anywhere for basic meeting places and grinding resources and instances where players can play cooperatively.

With regards to servers. We're thinking of having a number of copies of the main world, each with its own dedicated server / bandwidth. We were also thinking of having a number of servers dedicated purely to instances

With regards player accuonts. When a new user signs up this is done on a completely different secure server to protect the players personal information. We arent too sure on the best approach when it comes to handeling players game state on the server though. Originally we were planning on utilising a SQL database to store game state information, but we also heard that using the local file system may be a better approach? If we went the file system route then we were thinking of storing each users current state in its own unique file that is updated either every time something for that user changes, or every so often (maybe every few server ticks). Along with unique player files, we would also keep a player info file that contains basic static or rarely changing information about all players, allowing easy searching. Not sure, whats the standard for massive user games?

We're planning on using TCP all the way. We already have a basic server up and running using TCP. We're just in the process of rewriting it to take over the game logic.



Quote:Original post by hplus0603
There are all kinds of fun problems that pop up with this design.

For example, if you send updates only when entities are within scope, and an entity goes from within scope to out of scope, you'll stop sending updates -- but is the client to treat this as "out of scope," or as "is just doing nothing, still at its last position"? One solution is to explicitly manage scope to the client, telling it about out-of-scope events.

Another problem is that of physics; if players block the passage of other players, you will have all kinds of rubber banding and lag with a naive implementation.

However, it's a good start, especially if you're just doing it to learn and/or for fun. Don't let the problems dissuade you! I'm glad you're talking about what you're doing, rather than how great it will be when you're done -- because it won't :-) Talking about what you're doing is always allowed (within limits of decorum, of course).


The plan with regards to deciding who gets what messages is gonne be done using distance. Players are sorted by diatance, those that are closer will receieve messages at a faster rate than those that are far away. Those that are too far (out of sight) will not receive any messages from the player (except text messages). Does this sound fine?

With regards to player to player collision, we're not gonna have any :)
Quote:Those that are too far (out of sight) will not receive any messages from the player (except text messages). Does this sound fine?


Re-read my section about what happens when a player goes out of scope from another player, from being in scope. How will you handle that case?
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement