Hi TufanMeric,
I’ve been working on a game with some similarity to the one you mentioned.
Here’s some things to consider:
1. 60 updates per second seems excessive. Even 30 might be more than necessary if your players don't change velocity quickly. I send 20 per second, i.e. one every two physics frames. Instead of trying to send an update for every rendering or physics frame, send fewer updates and smooth/interpolate/extrapolate the motion client-side.
2. Don’t send clients irrelevant data. The client does not need to know about things that are out of its view. For my game, players only receive updates for other players and events within a distance of 1000 units, i.e. just further than the player can see. Things that are further away but that the player would still hear (e.g. gunshots and explosions) are sent as 3-bytes (1 byte for the id of the sound to play and 2 bytes for an approximation of the location).
3. Each packet you send comes with significant overhead, so try to reduce the overall number of packets. For instance, my client, rather than sending a separate packet to the server every time the player fires a bullet, appends the necessary information about the bullet to the outgoing movement updates. Since the client is sending movement updates 20Hz and the game’s physics run at 40Hz, my players can only fire bullets on even numbered physics frames, but in-game this restriction isn’t very noticeable.
4. Try to pack your data densely. Often, data does not need to be sent in the same format or resolution in which it is stored locally. For example, my client sends position data as well as input data. It sends the player’s last four X/Y positions (two of which will be new for the sever and two for the purpose of redundancy to reduce the effect of lost and out-of-order packets). Locally, these values are stored as floats. That’s eight floats, or 24 bytes. However, as the maximum play area is 7500x7500, I send the player’s current position using 2-byte integers and thereby achieve a resolution of about 0.11 – the inaccuracy is totally invisible. Then, because players can move at most 3.5 units in a single physics frame, the other three positions are sent as 1-byte relative values (which provides a resolution of about 0.01). So instead of sending 24 bytes of positional data, I only send 10. Ditto for input: all the player’s input can be packed into a single byte rather than sending a separate byte for every key.
My examples mainly concerned client-to-server communication, but naturally, the same applies to data flowing the other direction.
What do your update packets look like?