Server position relay to clients instantly or delayed

Started by
2 comments, last by rpiller 11 years, 3 months ago

I'm making a casual MMO style game. No real "action" or fighting or anything like that is happening, just building a social world (just, like it's that easy huh smile.png ). Because of this I feel like my need for position data isn't all that intense. I'm going to have the clients send breadcrumbs (their actual x,y position value) of their positions and just have the server validate the breadcrumbs are reasonable to prevent cheating.

This is a 2D top/down style game where the players move relatively slow so I'm thinking sending position data about 4 times a second is good enough. I have this code running now and it seems fine when client/server is on the same PC.

My question is, on the server side, is it common to instantly broadcast the position of a player when that player sent the server the position data OR on a more timed basis on the server? More specifically I have a function on the server side that gets triggered whenever a client sent it's x, y. I read the x, y value in this function. Should I also broadcast to all other players this new value in this same function, or should I store it, and on a timed interval broadcast out everyone's position?

I feel like the timed interval is a cleaner approach but it also might create "bottlenecks" as a "large" chunk of data is being sent at a pretty regular interval vs a more constant stream of data that can be more unpredictable and is more based on the number of clients connected and their 250ms timer sending positional data. On the other hand I think a constant stream of smaller bits is smoother than a large chunk of bits at a given interval. Which side of my thinking is correct? smile.png

[edit]

Also I will only be broadcasting positions to those clients in a given radius to said player.

Advertisement

I had to program the same thing as well (just for a 3D game) and my current solution is this:

Whenever the server gets information about one clients position, he simply saves it (no cheat-prevention yet). As soon as he comes to the main loop,

the position of all clients nearby a specific client is sent to that specific client.

Since I have to transmit much more data than that (terrain, objects, actions, ...), I ran into those bottleneck problem you described.

To prevent these problems, everytime the server wants to send something to a client, he tells a client-object (i´m doing java, object-oriented) the data that he wants to send him. This objects simply saves all the data that is to be sent and from time to time the main program tells all client-objects to send a bunch of data. The client-objects now take the first 310 bytes and send them to the clients. Therefore, no problems with sending too much data is eliminated.

But maybe, I went to much in detail. I don´t know how much data you have to send altogether, but if it´s just a few bytes about position, you should be fine just sending all at once. The chunk of data shouldn´t be that "large".

Well, id still consider myself new to networking but here is my opinion.

Since your making a MMO I really don't think thats going to scale to well as more and more players connect (it looks like ur using a thread or two per client). You will end up with 1/2 threads per connection on the server (500 connections may equal 1000 threads or more!).

Do this instead:
- each client can have a download/upload buffer (just large array of bytes)

- forget about the 250ms messaging timer

Here is my attempt at explaining in detail:

In a game I am soon making I will only allocate a thread to a client when the client first connects, in this thread the server/client communicate and verify each other in a non-asynchronous/blocking way), after that is successful the client is added to the list of players and the newly created thread then terminates (as I said though required client information is added to the list of clients - including the tcp (or UDP IP/port) connection.

The primary server thread which does the updating of the world (main game loop) iterates through each client and updates accordingly, before that happens however the server also checks all clients for any available data to be processed, collects the data and processes it using a prefixed length messaging algorithm. The client download buffer is also used here for processing the messages if they come in small bits at a time. If a successful message has been received which involves a movement of a player's position and is then process upon... all other players/connected clients have their upload buffer added to indicating that a player has moved. At the end of the game loop the server then iterates over all clients once again and clears out all buffers by uploading the data.

Edit: also make it so data is only sent by the client when a player actually moves and handle that accordingly, even if the player spams left/right that's really only a maximum 24 bytes per message - and you cant really prevent denial of service.

So really this is just making messages basically instant - but in a way that doesn't involve many threads.

The batch idea is interesting. I'm using RakNet and used to sending messages where the first byte is the message ID and the remainder data is the data for that message type. Batching things up with this way wouldn't really be byte oriented but message oriented. However RakNet is doing the sending behind the scenes is something I don't have to worry about really, which is nice. I can focus on sending messages and data that the messages require.

I think to start with I'll just send the new positions from the server right when the server gets it (if the position changed from last time) to all the other clients around said client. I'll make a separate process every second or so that refreshes the clients around each client since that doesn't really need to be done on each send in a slow pace casual game like this. I don't personally have any threads, but RakNet does to do the networking as it's async. All the decisions to send and read the data from RakNet is done on my 1 main thread.

I think this will create a steady, but unpredictable, stream of data leaving the server. That's for sure better than the predictable bottleneck of sending all data on a given interval, but not as ideal as predictable with a cap. I have to wonder if predictable with a cap sent each time leads to other issues of falling way behind and then having to deal with that. Not that you can't deal with it, but it's just another thing to deal with. I think for now I'll just send out instantly the positions when they have changed.

For other reasons I want the client to always send their position 4 times a second no matter if they moved or not. It's complicated to explain but has to do with the streaming map data sent to the client and a small situation that can happen that is corrected by getting constant position updates. 4 times a second is nothing considering a good number of action games can do 20+ a second.

This topic is closed to new replies.

Advertisement