Advertisement

MMO Server functionality? [Unity3D]

Started by December 12, 2013 10:22 PM
6 comments, last by hplus0603 10 years, 11 months ago

I've created a multiplayer server for Unity that works like this:

  • Every client/player connects to the server and says 'hi'.
  • Server accepts the player and adds him to the players online list.
  • Every client start sending his position.
  • Server listens for client's positions and X times per second sends them to all other players online.
    • This is made by one bucle on all online players, so the server is configured to send say 10 times per second the updated positions to all the players.
  • Every client listens the server for other players position. When the server says "this player just said he's there", the client moves him there.

With this basic system, I can create a multiplayer game with Unity easily (already did it). But what if there's more than a couple of thousand players online? Then, say that every player sends his position to the server about 10times/sec. And the server has to send those position to all players around, say 100m. So, the server would run a loop for all online players (2000) comparing his position with the all 1999 players and if it's less than a 100m, send the position to the player. Or, maybe better, save all the players updated position in one array and send it to the player. (Only one message every 10s to the player should be better than hundreds, right? Anyway, the loop has to go through 2000*1999 10 times per sec, that could be painful..

I want to use Unity3d as client, I don't want to hold any physics on the server because using the unity's physics engine is good/fast/easy to work with. And I think it could be enough, maybe do some anti-cheating checking on the server-side just to get rid of badplayers.

Now, the questions :)

  • How does a proper mmo server work? Does every player send its position to the server X times per second and it goes through that HEAVY loop and sends his position to all players around? what about performance?

  • I would implement a prediction system for the next move and interpolate the current position wit the updated one received from the server. is it right?

  • If I have to detect player collisions with each other or with objects (bullets and more) would you do it on the client-side? or implement a players-player & player-object collision detection system in the server side and do it in the big loop?

  • If the player moves is with the keyboard so it doesn't have just a single position to go, how would you send the position to the server, like 10times per second and interpolate the position received by other players to create a smooth movement?

  • If the movement of the players is by setting force physics to them, like when you go forwards it's because there's a strength pushing you, how would you transmit this information to the other clients? Send just the position to the server and it sends it to the other players? But then, the physics would look weird... The plan b) I thought of is to send the force used to the server and every clients applies the force received by the server to all the players around them, physics here would look awesome but maybe there's a latency problem... Would it be good to use this system and send the exact position every X time? say .5s?

Well, I think this is all! I hope this post can be useful for other indies!

This problem is called "interest management," and it really is a problem if you allow all 2,000 players to all be in the same area (market square, or whatnot.)

After all, if everyone is in the same square, they should all see each other, so you need to send the position of 2,000 players TO 2,000 players, so you're sending 4,000,000 positions out from the server in one update loop.

You also want to manage the client's network bandwidth -- although most users have some form of broadband these days, 1.5 Mbit is still common and is not that large an amount of bandwidth.

One pretty common approach, is to divide your world into cells. Each player is linked into a list of "players in this cell." If you have a fancy cell/portal world file, you may be able to do it that way; else it's common to use square cells of some size (say, 50x50 meters.)

Then, you send updates only for the players in the same cell as the player, and the neighboring N cells (each direct neighbor for a square set, say.)

When players move around, you remove them from the cell they're in, and put them in the cell they're moving to.

If you still want to support the 2,000 players all in the same city square, then you also need to implement prioritization, where you send fewer entities per update, and send the most-out-of-date entities in each packet. You may also want to prioritize any team members, and any fight targets, for example, and send those more often.

Also, when you stop sending updates for another player, you need to send a "discard this player entity" message. When you start sending updates for another player you haven't seen, you need to send a "this is what this player is wearing" message. If you have a lot of churn in visibility, your connection may see inefficient use of bandwidth, and it might be better to use some hysteresis -- prefer to keep updating an entity you already have in view,rather than switch to some other entity that is only marginally closer/better; don't switch until the non-updated entity is at least X better than the worst currently-visible entity.

Interest management, and prioritization, are only two of the many reasons why an "online multiplayer RPG" and a "massively online multiplayer RPG" really are two totally different kinds of games :-)

enum Bool { True, False, FileNotFound };
Advertisement

I think this post may be relevant to you as well:

http://www.gamedev.net/topic/650983-so-i-want-to-make-an-mmorpg/?view=findpost&p=5115552

hplus0603 hit on this point with his online vs massively online comment.

- Eck

EckTech Games - Games and Unity Assets I'm working on
Still Flying - My GameDev journal
The Shilwulf Dynasty - Campaign notes for my Rogue Trader RPG

This problem is called "interest management," and it really is a problem if you allow all 2,000 players to all be in the same area (market square, or whatnot.)

After all, if everyone is in the same square, they should all see each other, so you need to send the position of 2,000 players TO 2,000 players, so you're sending 4,000,000 positions out from the server in one update loop.

You also want to manage the client's network bandwidth -- although most users have some form of broadband these days, 1.5 Mbit is still common and is not that large an amount of bandwidth.

One pretty common approach, is to divide your world into cells. Each player is linked into a list of "players in this cell." If you have a fancy cell/portal world file, you may be able to do it that way; else it's common to use square cells of some size (say, 50x50 meters.)

Then, you send updates only for the players in the same cell as the player, and the neighboring N cells (each direct neighbor for a square set, say.)

When players move around, you remove them from the cell they're in, and put them in the cell they're moving to.

If you still want to support the 2,000 players all in the same city square, then you also need to implement prioritization, where you send fewer entities per update, and send the most-out-of-date entities in each packet. You may also want to prioritize any team members, and any fight targets, for example, and send those more often.

Also, when you stop sending updates for another player, you need to send a "discard this player entity" message. When you start sending updates for another player you haven't seen, you need to send a "this is what this player is wearing" message. If you have a lot of churn in visibility, your connection may see inefficient use of bandwidth, and it might be better to use some hysteresis -- prefer to keep updating an entity you already have in view,rather than switch to some other entity that is only marginally closer/better; don't switch until the non-updated entity is at least X better than the worst currently-visible entity.

Interest management, and prioritization, are only two of the many reasons why an "online multiplayer RPG" and a "massively online multiplayer RPG" really are two totally different kinds of games :-)

I know it's a hard-example but think of world of warcraft, I could split users in regions say (50x50m) but what If one is in the border of a region and the other in the border of another region, then, they should see eachother but being in different region-clusters/servers would make them invisible for each other. How would you solve this? Thanks :)

If one is in the border of a region and the other in the border of another region, then, they should see eachother but being in different region-clusters/servers would make them invisible for each other. How would you solve this? Thanks smile.png


Then, you send updates only for the players in the same cell as the player, and the neighboring N cells (each direct neighbor for a square set, say.)


You can save minutes of having to read carefully by waiting hours for a question to be answered :-)
enum Bool { True, False, FileNotFound };

Making an MMO is going to be very hard if you have to ask this, however, this concept needs to apply to ALL of your systems.

"The only work done right is the work other clients don't know about".

That is, you need to zone up your levels, and occlude people who don't need to know about certain stuff.

For example, let's make a highly detailed map to illustrate.

A... B... C.... D

Player bob is in zone B. Other players in B need to get information as to what bob is doing, but they ONLY need to get it updated based on how far away bob is. If he's 200m away, but the payers can see each other, bob only needs to be updated a few times a second (Or even less). As those players get nearer, bob needs to be updated more often.

Let's say Bob's bored of Zone B, and he goes to adventure towards zone C.

Zone B says "Hey C, there's this cool guy called Bob coming your way. He's about 100 meters away from you. Is anyone near your zone's edge with me?

Zone C responds "Oh yeah, my edge is populated by 1 person, and Player Rob should be able to see him if Bob's 100m away". Those 2 zones then need to send Bob and Rob relevant information so that the transition is seamless.

Everything you do needs to be based off of this principal, otherwise you're just going to shove too much working data down your client's pipes (Or melt your servers).

Zones with no players in, or nearby should be spun down so they don't waste processing time,

Note though, I'm not really a game developer, but I'm a high speed data transaction engineer. Also, I've never used Unity.

Advertisement

If you have to ask... (the answer is usually no) smile.png

But here goes:

1. A proper MMO server doesn't actually exist, although you could argue that the location, or its named entity could be called a server.

You can see this in World of Warcraft, where the server names are from their Lore.

In reality, an "MMO server" is actually hundreds of server nodes which communicate to the absolute minimum protected by outward facing proxies.

The proxies are entry points from clients protecting the inside network of nodes. Nodes can be divided by purpose, such as economy, accounting, tracker etc.

MMO servers are actually, almost exclusively mesh networks.

Geography zones are also almost exclusively mesh networks. Typically just called nodes. Some games split people into different nodes even on the same location to lessen the burden, such as Age of Conan.

2. You cannot predict player movement, but you can certainly just interpolate it in a straight line. People tend to move mostly forward with their player, so linear interpolation will work more than not. I guess you could call it lazy prediction, but it's cheap and it works.

3. You can do all checks client-side which potentially could reduce the load on nodes, because they wouldn't have to go deep into collision checks. Sometimes.

You can never skip any server-side checks, ever. You will be overrun with hackers, and be punished heavily. This is why most MMOs don't do collision at all (against other players, or even mobs).

4. You would send movement updates to the absolute minimum possible extent. This means, if I move forward with my player, the client tells the server; "I'm moving forward now." And so both the client and the server keeps moving me forward until I tell it I stopped. Interpolation and semi-regular updates takes care of the rest.

5. You cannot use force physics from players against other players easily, except if you are a billion dollar company. Or you have a high speed arena game, where low latency is key. The company example would be blizzard with WoW, as well as arena game being Valve with Dota 2.

I'm not sure if I understand your question.. but it doesn't matter what update frequency you use. Actions that impacts other players position need to be instant down to under 100ms to be even remotely competitive. This requires serious bandwidth in a *MO scenario.

Even the big companies cannot beat reality: Most people have too much latency, compared to what they should have. Perhaps not the western world, on average. But low latency networking across the Internet (for everyone) is something we will look toward the future for.

I hope I have answered your questions at least somewhat. No. 5 is, or seems, to be honest, naive. The fact that you are asking these questions at all, which are basic networking paradigms, suggests to me that you are perhaps aiming to the sky, and towards the neighboring galaxy.

If that is the case, permit me to suggest you implement a serious multiplayer game before anything like this. Otherwise, I hope your curiousity was sated a little.

This is why most MMOs don't do collision at all (against other players, or even mobs).


Actually, the main reason you don't collide against mobs or other players is gameplay related. It's too easy to troll other players with collision-based blocking otherwise.

It is true that actor/actor collisions is very hard to do well in a way that both is physically accurate, and feels instant to each player. Typically, at least one player will see some kind of rubber-banding or delay in actions. However, for some games, this works just fine; especially games with slower movement/acceleration models that can afford to show the local player based on the data coming back from the server, rather than based on local extrapolation.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement