2
\$\begingroup\$

So the way that I tried to create a MMO like server communication was by sending strings to every-player containing information and making the client split the string.

Example

"John" , 42, 64 : "Bob", 0, 0 : "Lilly", 1943, 120

This worked make it so for every ':' it would create a new character with the following information. And just send it to every-player connected. But once I added bullets and the game world, this started getting long and hard to manage.

Example

"John", 42, 64 (42,43 / 45,12 / 45,12, / 46,5 / 12,5), "Help Me", "Running", "Red", "Red", "Blue", 12

I have made a Async multi-client fast server, which works very well, but how can I send information through the server so every client can respond to it correctly.

So for example:

  • You start the game it connects to master server (Done)

  • You get added the servers player list (Done)

  • Make so you spawn as a character on everyone's else's screen and move in real-time every update. (Problem)

Is there any way to get this working with-out using this really long string? I hope I explained this question clearly.

\$\endgroup\$
1
\$\begingroup\$

The server should send a new information to the clients only if there was a change in behaviour in one of those clients (input from a player) - and then only send the information about the change.

So to extend your example (this might include lot of stuff that is obvious to you, but just for the clarity...):
Player connects to the server:
- Server looks up all the information about the player that is needed for the clients to display him properly: at minimum this would be the position. Depending on the game we're making this would also include things like rotation, state, character appearance etc. (though for example the appearance can generally be loaded later and a placeholder can be displayed instead). This information is then send to every client (including the player). And we are not going to send this big bulk of information together again.
- Clients create this new player based on the information they received and the player now also knows what his position is so now we can render the world around him. The player would also need information about other players that are nearby - this also could have been sent to him in the previous step.

At this point every client should see everyone that is nearby.

Player wants to move forward:
This is very game dependant (is the movement "click to move", WASD, something else?) but let's consider the option where while the W keys is pressed, the player is moving forward. Two things should happen when the player presses the key. First, this information and nothing more is sent to the server. So the server receives a message that "John", whatever he's doing right now, wants to move forward.
Meanwhile on the player's client the second thing happens as we can start performing the forward movement no matter what's going on on the server (look up movement prediction for more information).
After receiving the information, the server checks if the movement is possible and if it is, sends the movement data to the clients. The clients should already have this player's position and rotation, so we don't need to send it again (although you might want to do that for synchronization purposes, but that can be performed at a different time).

The player shouldn't send anything concerning the movement after that. The server and the clients should all now perform the forward movement calculation inside their own update methods, until the player stops pressing the W key. Then we send a new message like before containing only player ID and that we doesn't want to move anymore.

We can apply a similar approach to rotation, shooting, state or changing appearance. When the player presses the "shoot" button, the server gets notified, and can just resend the information to the others, or can attach direction vector as well to ensure more synchronized behaviour.

\$\endgroup\$
  • \$\begingroup\$ Wow, thanks just one last thing to clarify, how will I send this data across? For example would I send "Action : User4012 : FiredBullet : 412,142 to 922, 943" and then the server would send back "Reply : User4012 : FiredBullet : DestoryAt : 813, 813" because the server knows there's a wall there? How do I send the information to all the users neatly? \$\endgroup\$ – John Aug 1 '15 at 10:57
  • \$\begingroup\$ Because you can only send bytes across which can be decoded into ASCII as you most probably know. Or bytes which can be serialized into a object. And if I send the information "John walked forward 12" as a string the server would need to go User:"John Action:"Walked" Direction:Forward" Speed:"12" which works but thats only because the string was that long for other lengths it will crash. Is there a way to send information and commands neatly. For example some unity projects can use this: Stream.Get(ref Health) and it gets there health! \$\endgroup\$ – John Aug 1 '15 at 11:02
  • \$\begingroup\$ As to what the client sends to the server and vice versa, the question is - do you really need to? In your example, you don't need to send the position from where the bullet was fired - the server is supposed to know the player's position and also you don't want to rely on this kind of information from the client (to avoid cheating by sending incorrect data to the server). \$\endgroup\$ – Martin Ciz Aug 1 '15 at 12:53
  • \$\begingroup\$ How to send it? Depends on the solution you're using currently, but unless the networking part is the reason you're doing this project, I recommend you to have a look on SignalR library. It's not only for website stuff, any .NET client can benefit from it. It's simple and neat: ) Basically you can specify methods on both client and the server that each other can call as methods and that's it! No worrying about how to send the data, it handles reconnecting and other good stuff for you. \$\endgroup\$ – Martin Ciz Aug 1 '15 at 12:53
  • \$\begingroup\$ Almost complete, but the W-press forward movement is a critical point. As frame rate stability and floating point calculation vary (at least theoretically) you should either synchronize the position at a specific interval (which would make big sync differences very awkward, even if interpolated) or simply let the server send the positions all the time to the clients which would allow UDP as packet loss would not be recognized if the packets are sent on regular timesteps (10x-15x per sec.). As this protocol supports multicasting, the needed bandwidth and sending power would not be pressurized. \$\endgroup\$ – Doctor Niklas Aug 31 '15 at 16:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.