3
\$\begingroup\$

I am currently writing a server for a multiplayer game. I am trying to find a good solution for synchronizing GameObjects across the server. The server sends each client a snapshot of every object in range over TCP once every 1/15th of a second and it sends minor updates over UDP every 1/30th of a second. I've come to the point in the code where after I've handled login and the basic information exchange I need to start synchronizing objects between the client and server. My original solution was to keep a boolean flag inside of each GameObject class to tell if it had been changed that update cycle or not and then send a serialized version of it across the server. However, the problem with that is that that sends the entire object even if only one variable was changed which wastes bandwidth not to mention the fact that I would need to serialize a representative class and not the actual one that may contain information that should only be server-side. A friend proposed the solution that I should write a class that contains a HashMap of variables that maps Strings to NetVars(a class containing the value and an index for referring to it). All variable changes would go through a get and set function so that we could tell if it had been modified. Each GameObject would keep one of these and when the server goes through its update cycle it would send the updates as a serialized list of NetVars that have been changed for each object to the clients who should receive them along with the object's id.

My question is would that be too much overhead? Would it slow down the server by having a NetVars class for each GameObject? and finally are there any better solutions than these and if so what?

Extra info: Using Java with Kryonet for networking and the game is expected to have a fair number of entities in player view at any one moment.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Just a note: your updates are too frequent, an "average" ping of 100ms will eat any advantage you hope to gain by spewing out so many packets. There's just no way around having to do client-side work. If you drop down to 1/10sec you just shaved your bandwidth requirement to 30% of the original and without getting into state caches. \$\endgroup\$ Apr 24, 2012 at 1:10

2 Answers 2

2
\$\begingroup\$

This would be fine; in fact, most games have some variation on this method, tracking individual variables that change and only transmitting those variables.

You can still have the per-object flag; that saves you from having to examine every field in the object when none of them have changed. Just make sure that your interface keeps everything in sync, so there's no chance of accidentally changing a variable while leaving the object flagged as unchanged. (Although there are times you may want to allow this, eg. for objects that you don't want to broadcast too often, maybe because they're uninteresting, or distant, etc.)

You may not need a hashmap: if your objects are identical at both ends of the network then a simple index will suffice for noting which field has changed.

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

Keeping a hashmap per object is unlikely to cause too much overhead.

Justification: Python's Objects are essentially hashmaps ('dicts' in the parlance) and it is possible to write this kind of client/server program in python up to a surprisingly good level of performance.

Besides which, in most cases, the nework latency will dwarf the processing costs by orders of magnitude, especially for something as well optimised as a hashmap lookup. In fact, it will almost always be worth compressing your message to improve network performance.

\$\endgroup\$

You must log in to answer this question.

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