I am making a multiplayer game in Java that uses a client-server model, where all important decisions are made by the server and communicated to all clients over UDP. Currently the clients and the server both send packets at 30fps. The clients just send a single packet each time, but for the server the situation is a little more complicated.

The server needs to update the client on the positions of all Entities in the game, of which there could be many (100+) at any given time. Currently each of these updates is being sent in a separate packet.

It seems to me that combining some of these updates into a single packet could be beneficial, as it would reduce the overhead of creating and sending all these packets. But combining too many updates would create a packet that is "too large" to be sent efficiently across the network.

Where does the balance lie between packet size and the number of packets being sent, in order to achieve the fastest and most reliably delivery?

up vote 4 down vote accepted

According to the answers on this page, about 512 is a safe amount for ipv4 because nearly all consumer's hardware will be able to support that size. For ipv6, 1500B is the maximum safe packet size. Subtract 40 + 8, the ipv6 and UDP header sizes, and you get 1454B maximum data inside that packet. If you send something over the limit, it's most likely going to be cropped out. With some clever compression methods, you should break the limit very rarely so a simple check then to send out an additional packet should work fine.

If you have 100+ entities, 30 syncs per second will simply not be viable. If you're just syncing positions and rotations, which together is i.e. 24B, the bandwidth demand per second will be 24 * 100 * 30 = 72,000. Assuming that spatial and delta compressions are used, this number can dwindle down to i.e. 32,000. Then there's the packet headers which will be negligible compared to the data within the packets: (40 + 8) * 30 = 1440. Now, this is much, much better than syncing entities with individual packets (216,000B/s) but 33,440B/s is still a hefty amount, especially since we're only considering positions and rotations (not bullets, health, etc.). If every one of those entities was a player needed to be synced, this tasks the server to send out 3MB/s of data for a single room. To put things into perspective, an hour long game hosted on Amazon EC2 would cost about $1.50. If you make a profit of $10 off a player, you would start losing money from that player after he has played 660 hours.

Conclusion:

A lower sync rate is definitely called for and spacial culling must be used extensively in order to make the data size manageable. You haven't specified if you're using ipv4 or ipv6 but you should probably use ipv6 so you can fit more data into a packet.

Sidenotes:

I would recommend using a lockstep model for anywhere of 32+ entities. Actually, I think almost all multiplayer games would be best off using the lockstep model because of the unbeatable bandwidth efficiency and hack prevention.

If you don't want to deal with indeterminism or want players to be able to join mid-game, look at PlanetSide 2. They use a semi-authoritative server that syncs thousands of players with 5 syncs per second, clever extrapolation, and spatial culling. Granted, the game is far from perfect and very laggy but it gets the job done. What I mean by semi-authoritative is that the server is only authoritative about what is most important and practical (positions, deaths, abilities). Being authoritative about every single projectile would lead to many weird bullet behaviors when shooting because of the lag.

  • 1
    Thank you very much for the detailed reply. It was helpful to think about the problem numerically. Clearly I will need to move towards a more clever solution. I will look into using a lockstep model. – Dan May 22 '15 at 8:30
  • According to tools.ietf.org/html/rfc791, all IPv4 interfaces must accept a minimum datagram size of 576 octets. 512byte plus some overhead bytes for IPv4 will still leave a small handful of bytes that could still be used, but 512 is a nice easy to remember number. Even though the minimum packet received is 576, the minimum to send is 68 octets. – Bengie Dec 28 '17 at 1:13

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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