Our game relies on a lot of data being sent to and from the server. The data is serialized into JSON before it is transmitted over the wire.
Instead of handcrafting the packets by hand for each request, we have a generic system that allows us to keep the logic that deals with serialization centralized. This happens in our SerializationUtility and GameProperty classes. We define our own types that can be transmitted, and for each of those we implement a way to serialize it. Any time we need to transmit data, we pack it in one of those properties.
To make this easier to use and nest, we wrap these GameProperty instances in a PropertyCollection class which is a key-value store that identifies each property by a string name. Any class implementing the IPropertyHolder interface will contain a PropertyCollection that is exposed. Server Events, Actions, Game Entities, and Entity Info are all examples of property holders.
This approach, however, poses a challenge. Since the client and server need to both agree on the property names and what they mean, the key used on both sides must always match. This also makes it easy to break one side if the key is changed or a typo is made on one side but not the other. So to address this, we rely on decorators (called wrappers) that provide properties that encapsulate the key name and any special handling needed. These wrappers are shared between the server and client, thus ensuring both remain in sync all the time. We should never access a property directly by its key except in the wrapper classes.
Comments (1)
Comments are closed.