Networking and optimisations

Sorry for the lack of updates for the past couple of months, I was away visiting family and things for some of that time, but I have also made a lot of progress on the game.  So let’s dive in!

Networking layer

Most of my time lately has been spent on networking code.  As I discussed in the previous post, the Unity networking API situation at the moment is unfortunate to put it mildly.  To mitigate against this, I’ve now built a new networking abstraction layer.  This wraps and hides away all direct access to the deprecated Unity RakNet based API that I’m currently using, and should facilitate easier migration to a different networking API in the future.

This was a big task as it touched code throughout the game.  There are four major aspects to the networking API that needed to be eliminated from the game code: Network static API, network messages, NetworkView, and NetworkPlayer.  In more detail:-

  1. Network static API, e.g. Network.isServer, Network.SetSendingEnabled(),
    etc.  These are now only used inside the networking layer (or where
    absolutely necessary, wrapped behind a new API for use in game code).
  2. Network messages, e.g. OnServerInitialized(), OnPlayerConnected(), etc.  These are now only used inside the networking layer, and where necessary propagated out to the game code via events.
  3. NetworkView, used for remote procedure calls (RPCs) and state serialization:-
    1. RPCs.  The new layer now allows game code to register methods,
      then remotely call, and receive them.  Internally this currently is
      still implemented using a NetworkView and RPCs.
    2. State serialization via OnSerializeNetworkView() and BitStream.
      I’ve now implemented a system within the networking layer to
      synchronize state across the network.  Internally this is still
      implemented using a NetworkView, OnSerializeNetworkView(), and BitStream, but none of this is exposed to the game code.
  4. NetworkPlayer, used to uniquely identify a connected player.  Now
    the new networking layer assigns its own ID for each player, and keeps a
    reference to each player’s NetworkPlayer for use internally only

After of all of these changes, the Unity networking API is no longer directly referenced anywhere in game code.  The next step will be to actually change the networking layer’s internal implementation from using the Unity API to something else.  This will likely still be a painful task, but should be far more manageable now than it would have been before.

Construction modification optimisations

In the previous blog post I talked about the optimisations I’d done to the construction modification code (this code deals with attaching and detaching parts).  The performance of this code is particularly important in the context of the damage system which can require a large number of parts to be detached at once.

I have now implemented a GameObject pooling system, which eliminates the last major remaining performance cost, that being the instantiation and destruction of construction and Rigidbody GameObjects.  In the example I showed in the last post (shown again below), the cost of breaking the attachments is now down to less than 10ms (prior to doing any optimisations, it was around 60ms!)


There are still more optimisations I can do.  For example, the instantiation and destruction of the attachments between parts are contributing some performance cost (and GC allocs).  Plus, associated with the attachments are the physics ConfigurableJoints between Rigidbodies, which also have to be created and destroyed.  Maybe I could pool these too, something to look at in the future for sure.

But for right now I’m happy enough with the performance that I can get back to working on the damage system.

Damage system

On which subject, I’ll be returning my focus to this next.  I still need to decide how to propagate collision forces to cause plausible breakage of parts.  Also, I’m leaning away from the idea of damage accumulation and attachment “health”, towards more of a probabilistic method, but I’m not entirely sure yet.