Client/Server MMO
-
- Posts: 386
- Joined: Sun May 11, 2014 12:13 am
Client/Server MMO
Hey guys,
I've been working on a sort of MMO for a while now and the connection is giving me a lot of delay issues.
Like you'll move, and it'll take forever to see the movement on another client through a different internet connection.
I'm in the process of moving from TCP to UDP but I've checked to make sure things aren't overflowing with the same data, and the client is not sending duplicate information. So I don't think TCP is the issue.
Just wanted to clarify that my server/client is set up properly.
Here's what I'm doing:
Server has 1 thread for each new client.
Each server thread receives data from 1 specific client, then sends that data to every client.
The client has a non-blocking socket. It waits to receive information, and if it does, it stores it depending on the received client ID from the server. No threads used for clients.
Is there something other than changing from TCP to UDP that I should try? Because although making the switch could help, I'm wondering what else to do if it doesn't.
I've been working on a sort of MMO for a while now and the connection is giving me a lot of delay issues.
Like you'll move, and it'll take forever to see the movement on another client through a different internet connection.
I'm in the process of moving from TCP to UDP but I've checked to make sure things aren't overflowing with the same data, and the client is not sending duplicate information. So I don't think TCP is the issue.
Just wanted to clarify that my server/client is set up properly.
Here's what I'm doing:
Server has 1 thread for each new client.
Each server thread receives data from 1 specific client, then sends that data to every client.
The client has a non-blocking socket. It waits to receive information, and if it does, it stores it depending on the received client ID from the server. No threads used for clients.
Is there something other than changing from TCP to UDP that I should try? Because although making the switch could help, I'm wondering what else to do if it doesn't.
Re: Client/Server MMO
Did you disable nagle algorithm on tcp? It's a flag you can set - and if you don't disable it then tcp will only send out data once a certain buffer is filled. For games it's essential to disable that flag.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: Client/Server MMO
CuteAlien wrote:Did you disable nagle algorithm on tcp? It's a flag you can set - and if you don't disable it then tcp will only send out data once a certain buffer is filled. For games it's essential to disable that flag.
Nice tip!
Re: Client/Server MMO
From experience, you're running in an issue far greater than just switching TCP to UDP.
Like CuteAlien said, you can try disabling the Nagle algorithm, that may help the packets getting out of the client "faster".
Don't forget UDP packet are not garanteed to come in order. So, you may send the following packet :
1) Move bullet1 position to 10,10
2) Move bullet1 position to 20,20
3) Move bullet1 position to 30,30
... and receive them in this order :
1) Move bullet1 position to 20,20
2) Move bullet1 position to 30,30
3) Move bullet1 position to 10,10
What's going on with the bullet on screen when this happens? Do you add an order in the data you send? What happens when you receive a packet that you detecy is out of order, do you discard it and interpolate with the ordered data you have?
Like CuteAlien said, you can try disabling the Nagle algorithm, that may help the packets getting out of the client "faster".
Don't forget UDP packet are not garanteed to come in order. So, you may send the following packet :
1) Move bullet1 position to 10,10
2) Move bullet1 position to 20,20
3) Move bullet1 position to 30,30
... and receive them in this order :
1) Move bullet1 position to 20,20
2) Move bullet1 position to 30,30
3) Move bullet1 position to 10,10
What's going on with the bullet on screen when this happens? Do you add an order in the data you send? What happens when you receive a packet that you detecy is out of order, do you discard it and interpolate with the ordered data you have?
Re: Client/Server MMO
TCP is not a problem.
How big is your network?
There are games that are running on server side and distribute events using TCP/IP.
It can support hundred of players.
Some part of the game can be client side. E.g. physics. But skill execution or damage event etc. can be sent to the server for managing the ordering of execution.
For example game time stamp can be sent with each event. The server can use this for ordering of execution.
How big is your network?
There are games that are running on server side and distribute events using TCP/IP.
It can support hundred of players.
Some part of the game can be client side. E.g. physics. But skill execution or damage event etc. can be sent to the server for managing the ordering of execution.
For example game time stamp can be sent with each event. The server can use this for ordering of execution.
Re: Client/Server MMO
Unless you require extreme short delay, TCP is fine for everythign (but maybe a first person shooter or a fighting game). TCP has a lot of options to be setted and usually grants a higher throughput and data delivery which UDP (which however have shorter delay) doesnt'. When you handle more than a hundred of players you may start needed a more optimized protocol, most commercial engines use a optimized version of TCP (basically they emulate TCP over UDP removing all useless flags), but that affects reliability a bit (no longer proper congestion control).
UDP should be used only if strictly necessary because TCP really solves a lot of problems for you.
You should test your game by sending short events and waiting for a response (then measure time). Get a idea of delays and use them for testing:
How to testing:
There should be a communication API in your game, basically for each possible event you create a function to be called from the game, the function does nothing more than converting its parameters into a packet to send over TCP (so that the same function is called also on the server and eventually on clients).
Possible functions
When testing you can run the other players and server (even without graphics), on your local machine, adding random delays (your target PING +/- 50%) and seeing how does that affect the game so you can focus on stuff that improves the visuals for the clients.
Also I would not use a separate thread for each client. Threads add overhead in context switch, synchronization and much more programming syncronization issues.
Unless you are connectinga single server to thousands of clients each one performing dozen requests/ second, you can live with a single threaded server.
You can listen multiple clients on same socket without ever need to use threads. Basically everytime you read a message you process it. If you see you will get CPU capped much more time before you use all the bandwith available to your sever, then you can start multithreading it. Actually, bad synchronization could lead to huge slow down in response times (in exampe threads lock over the socket to listen)
UDP should be used only if strictly necessary because TCP really solves a lot of problems for you.
You should test your game by sending short events and waiting for a response (then measure time). Get a idea of delays and use them for testing:
How to testing:
There should be a communication API in your game, basically for each possible event you create a function to be called from the game, the function does nothing more than converting its parameters into a packet to send over TCP (so that the same function is called also on the server and eventually on clients).
Possible functions
Code: Select all
// Called by server to notify movement information of one player to another player
void PlayerCommunication::walkingTo ( playerID walkingPlayer, playerID notifiedPlayer, vector3df currentPos, vector3df currentSpeed)
{
}
// Called by a player to notify the server he's moving to a particular postion.
void PlayerCommunication::ImWalkingTo( vector3df currentPos, vector3df currentSpeed)
{
}
/*
Of course in reality you usually don't want 6 floating point values. Soemthing like player position can be updated more cheaply
(usually 2 integer coordinates for position, and since speed is fixed most times a single 2 bytes int to encode a direction suffice.
So you reduce data size from HEADER_SIZE + 24 bytes
to HEADER_SIZE + 10 bytes*/
When testing you can run the other players and server (even without graphics), on your local machine, adding random delays (your target PING +/- 50%) and seeing how does that affect the game so you can focus on stuff that improves the visuals for the clients.
Also I would not use a separate thread for each client. Threads add overhead in context switch, synchronization and much more programming syncronization issues.
Unless you are connectinga single server to thousands of clients each one performing dozen requests/ second, you can live with a single threaded server.
You can listen multiple clients on same socket without ever need to use threads. Basically everytime you read a message you process it. If you see you will get CPU capped much more time before you use all the bandwith available to your sever, then you can start multithreading it. Actually, bad synchronization could lead to huge slow down in response times (in exampe threads lock over the socket to listen)
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
-
- Posts: 386
- Joined: Sun May 11, 2014 12:13 am
Re: Client/Server MMO
Thanks for the clarification on TCP.
I'll be sticking to TCP then, since I've found it isn't the issue.
I'm using an std::vector to store information that will be sent from the server to the client and so-forth, then the server and client sends how many of these vectors it has received so that the client can send each with 0% packet loss (well, keep sending until received).
Basically what was happening was that when another client connected, there would be a short delay in sending and receiving, which would move the client back approx. 3 indexes from where he/she should be, and then any lag would continue to increase that number until it was way off.
I'm in the process of fixing the issue by not worrying if every vector index was sent, unless it's a priority and must be sent.
Thanks for the pointers, I've taken them all into consideration
I'll be sticking to TCP then, since I've found it isn't the issue.
I'm using an std::vector to store information that will be sent from the server to the client and so-forth, then the server and client sends how many of these vectors it has received so that the client can send each with 0% packet loss (well, keep sending until received).
Basically what was happening was that when another client connected, there would be a short delay in sending and receiving, which would move the client back approx. 3 indexes from where he/she should be, and then any lag would continue to increase that number until it was way off.
I'm in the process of fixing the issue by not worrying if every vector index was sent, unless it's a priority and must be sent.
Thanks for the pointers, I've taken them all into consideration
-
- Posts: 386
- Joined: Sun May 11, 2014 12:13 am
Re: Client/Server MMO
Fixed. Thanks guys
Re: Client/Server MMO
What did you do to fix your problem? Others may learn from this.
-
- Posts: 386
- Joined: Sun May 11, 2014 12:13 am
Re: Client/Server MMO
"by not worrying if every vector index was sent, unless it's a priority and must be sent."
-
- Posts: 386
- Joined: Sun May 11, 2014 12:13 am
Re: Client/Server MMO
I feel kind of like I'm reinventing the wheel, which is great practice for me to learn databases, but indie developing this game is taking forever so I'm thinking about switching to SQL to manage players.
Question - would I be able to use SQL to display players at an X, Y, and Z position? Or would SQL make that inefficient? Rather than sending doubles for those variables
Question - would I be able to use SQL to display players at an X, Y, and Z position? Or would SQL make that inefficient? Rather than sending doubles for those variables
Re: Client/Server MMO
Absolutely don't use SQL for that. SQL is pretty scalable, that means that you can "link" togheter several databases in several different machines so they can work togheter to up a million users (or two, but a million users is pretty heavy even for Postgres or MySQL). The problem is that when you have many players updating very often the database cannot simply sustain that amount of overhead.
Even though you manage to distribute your servers with a Cloud to be near your users, and you optimize tables with correct view so that each query takes at most few milliseconds you will have the following problems.
- You have already spent much more effort than doing the same without SQL
- You are paying insane costs for your servers (ok, you are basically using the computing power of a small social network for something that can be done in 1 cheap dedicated machine).
SQL is not the tool for the job. Especially if you think doing that without SQL is easier, then you do not have the skill for doing that in a "correct" way with SQL.
SQL is good for saving in a reliable way player progress once in a while. With SQL you don't have to warry about save files incomplete because "server shutted down". SQL never leave the DB in a unknown state (unless something vary bad happens, but in that case I think you have to recover your server directly XD).
Even though you manage to distribute your servers with a Cloud to be near your users, and you optimize tables with correct view so that each query takes at most few milliseconds you will have the following problems.
- You have already spent much more effort than doing the same without SQL
- You are paying insane costs for your servers (ok, you are basically using the computing power of a small social network for something that can be done in 1 cheap dedicated machine).
SQL is not the tool for the job. Especially if you think doing that without SQL is easier, then you do not have the skill for doing that in a "correct" way with SQL.
SQL is good for saving in a reliable way player progress once in a while. With SQL you don't have to warry about save files incomplete because "server shutted down". SQL never leave the DB in a unknown state (unless something vary bad happens, but in that case I think you have to recover your server directly XD).
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
-
- Posts: 386
- Joined: Sun May 11, 2014 12:13 am
Re: Client/Server MMO
Ah good to know.
I'll just stick to writing my own database. Thanks
I'll just stick to writing my own database. Thanks