7
\$\begingroup\$

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?

\$\endgroup\$
3
  • \$\begingroup\$ You should propably read at these two: en.wikipedia.org/wiki/Maximum_transmission_unit stackoverflow.com/questions/1098897/… => go for 512 bytes per datagramm \$\endgroup\$
    – VaTTeRGeR
    Commented May 20, 2015 at 22:02
  • \$\begingroup\$ Thanks for the reply. If I assume the maximum to be 512 bytes, then, is that also the optimum? \$\endgroup\$
    – Dan
    Commented May 21, 2015 at 8:11
  • \$\begingroup\$ It's not the maximum (you should not exceed ~1300bytes), but from what i read it is the optimal size to be very unlikely to get split up and lost. \$\endgroup\$
    – VaTTeRGeR
    Commented May 21, 2015 at 18:54

1 Answer 1

5
\$\begingroup\$

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.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – Dan
    Commented May 22, 2015 at 8:30
  • \$\begingroup\$ 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. \$\endgroup\$
    – Bengie
    Commented Dec 28, 2017 at 1:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .