Better building for multi-player

Most of my time over the past few weeks has been spent on a major reworking of the code for all of the tools in the game (builder, material, painter, etc.) in order to improve the building experience for networked client players in multi-player games.

Previously the tool code that responded to player inputs in order to perform various actions (such as attaching a part, breaking an attachment, applying paint, and so on) would always run on the server for all players, with each client simply sending their inputs to the server for it to deal with.  This setup made it relatively easy for the server to handle things like arbitration between players, seeing as they were effectively all running locally as far it was concerned.

However this approach was flawed, the most significant problem being the latency between client player input and an action happening, which made building really awkward to say the least.

So I’ve now re-implemented every tool so that player input is processed locally on each client.  In some cases the client must still request the server to complete certain actions, so that the server can validate and arbitrate where needed (for example, while one player is attaching one part to a second one, at the same time another player could be deleting that second part; the server needs to have the final say on the outcome in this scenario).  In many situations however, it is not necessary for the client to check with the server first (e.g. moving or resizing a selected part, painting a part, etc.), instead the client just informs the server of the change made so that it can be broadcast out to the rest of the clients.

The result is that the building experience for networked clients is now basically the same as it is in single player games.  The other benefit of these changes is that because input is processed locally for each player, it simplifies the code and makes it a bit easier to modify and improve the tools.

Builder tool tweaks

On which subject, I’ve made a couple of minor improvements to the builder tool thanks to some suggestions I’ve received.

  • Remove actions (delete part, destroy construction, etc.) are now delayed, during which time the action key has to be held down.  This should hopefully prevent annoying accidental deletions from mis-clicks!
  • I changed the default key binding for duplication from “Q” to “Left Alt + LMB”, by default “Q” is now dedicated just to opening the tool menu.

The usability of the builder tool controls is still an ongoing concern, and something I’ll have to keep plugging away at over time, but at least now it’ll be easier to implement any further improvements I need to make.

New demo coming soon

Finally, I’m getting close to releasing another demo build, and I’ve been fixing a bunch of bugs in preparation for this.  There have been a ton of changes to the code since the last demo, so I’m slightly paranoid that some as yet undiscovered bugs might have been introduced.  Time to do some more testing I think, hopefully I don’t encounter any last minute issues!

ScriptableObjects For Fun and Profit

Well, it’s been a while, so time for a progress update I think!  The material tool is now done, and I’ll show it in action very soon, so watch out for that.  Most of my time however has been occupied with a massive code re-architecture effort, and that’s what I’m going to go over in this update.

From a high level perspective the GearBlocks game code is quite well laid out in terms of separating various subsystems (e.g audio, graphics, player, UI, etc.) via namespaces and so on.  However, there was still a lot of code coupling (i.e. direct dependencies) between areas of the game code that should really be completely independent.  This made it impossible to reuse or test parts of the code independently, and it was only going to get worse as development progressed.

ScriptableObjects to the Rescue

I’d been using ScriptableObjects in Unity for a long time, but only in a select few cases as data containers, I certainly hadn’t been using them to their full potential.

I watched these two excellent presentations a while back:-

Ever since, I’d been wanting to adapt the ideas presented in these talks to the game to improve the code architecture, and so I finally decided to take the plunge.  This was a huge endeavour, but well worth it I think.

ScriptableObject Events

Previously I was using Unity’s ExecuteEvents system as the basis for events in the game.  This was helpful for code decoupling, however it still had some disadvantages:-

  • In order to add a new event, a new interface has to be written (derived from IEventSystemHandler), and then implemented in all the MonoBehaviours that need to receive the event.
  • It’s necessary to explicitly call ExecuteEvents.Execute() on every GameObject with MonoBehaviours that need to receive the event.  To me, this makes ExecuteEvents more like messages than true events, but perhaps that’s just semantics.
  • Only MonoBehaviours on GameObjects can receive these events, ScriptableObjects can not.

So I replaced these with a new system, where each event is now a ScriptableObject asset.  Here’s a simplified version of the code:-

public class EventAsset : ScriptableObject
{
    public delegate void EventHandler();
    public event EventHandler Handler = null;

    public void Raise()
    {
        if( Handler != null )
        {
            Handler();
        }
    }
}

The real implementation is slightly more complex, but follows the same principle.  It’s implemented using C# generics to allow for different event argument types, and has support for logging and listing the current event subscribers.  This is used by a custom editor I wrote to display this info while the game is running in the Unity editor, here’s an example of it in action:-

To use an event it can simply be assigned to a variable in the Unity inspector, then to receive it, just subscribe to Handler:-

public class Receiver : MonoBehaviour
{
    [SerializeField] EventAsset somethingHappened;

    EventAsset.EventHandler onSomethingHappened;

    void OnEnable()
    {
        onSomethingHappened = () => { Debug.Log( "I hear that something happened!" ); };
        somethingHappened.Handler += onSomethingHappened;
    }

    void OnDisable()
    {
        somethingHappened.Handler -= onSomethingHappened;
    }
}

Or to raise the event, just call Raise() on the event:-

public class Sender : MonoBehaviour
{
    [SerializeField] EventAsset somethingHappened;

    void SomethingHappened()
    {
        Debug.Log( "Something happened, telling everyone!" );
        somethingHappened.Raise();
    }
}

This setup has some useful advantages over the old ExecuteEvents system:-

  • No need to write any code to add a new event, just create a new event asset and assigned it in the inspector where needed.
  • No need to explicitly refer to specific GameObjects to send the event.
  • Don’t even need to be using GameObjects, these events can be used by ScriptableObjects as well as MonoBehaviours.
  • The events are more easily debuggable via the custom editor.

ScriptableObject Variables

Events aren’t always the most appropriate pattern for sharing data between subsystems, for example sometimes it’s necessary to store a value somewhere and allow it to be read a later point, perhaps continuously polling it to watch as it changes.

Previously I was doing this by having my subsystems be singletons, and then directly reading / writing properties in them where needed, thereby tightly coupling different areas of the code together, not good!  To solve this I made a new “variable” system, where each variable is a ScriptableObject asset.  Whereas events can be thought of as radio broadcasts, the variable system is conceptually more like a noticeboard (with each variable being a notice pinned to the board).

Here’s a simplified version of the code, it’s implemented as a generic class to allow for different variable types:-

public abstract class VariableAssetBase<T> : ScriptableObject
{
    [SerializeField] T value;

    public T Value { set { this.value = value; } }

    public static implicit operator T( VariableAssetBase<T> variableAsset )
    {
        return variableAsset.value;
    }
}

For example, a bool variable type:-

public class BoolVariableAsset : VariableAssetBase<bool>
{
} 

Again, the real code has a bit more going on.  It has an event delegate that code can subscribe to, in order to be notified when the variable value is assigned to (this saves having to use a separate event for this).  It also has support for serialisation so that I can use these variables for things like game settings (e.g. controls, gameplay, video) and allow the player to save / load them.  Plus I made a custom editor that allows variable values to be viewed or even modified while the game is running in the Unity editor.  At some point I might implement a debug console that would allow this to be done even in standalone builds, which would be super cool!

To use a variable it can be assigned in the inspector, then written to / read from.  Notice that Assigner and Watcher in this example are completely independent of one another:-

public class Assigner : MonoBehaviour
{
    [SerializeField] BoolVariableAsset isThingTrueVar;

    void ThingBecomesTrue()
    {
        isThingTrueVar.Value = true;
    }
}

public class Watcher : MonoBehaviour
{
    [SerializeField] BoolVariableAsset isThingTrueVar;

    void Update()
    {
        PollThingTruthiness();
    }

    void PollThingTruthiness()
    {
        Debug.Log( "Thing is currently " + isThingTrueVar );
    }
}

I replaced data in my subsystems that needed to be shared with these new ScriptableObject variables.  This allowed me to remove a lot of code dependencies, and eliminate the need for singleton references in most cases.

One example being the UI overlay that displays the player’s speed, acceleration, and altitude.  It now just reads variables for these values and displays them, completely independently of the player code that updates them.

ScriptableObject Dictionaries

There’s one slight wrinkle with the ScriptableObject variable system, in that there is only one global instance of each variable.  For example, sometimes I need one instance of a variable per player (in multi-player games).  To solve this I implemented a simple ScriptableObject dictionary, here’s the implementation pretty much in full:-

public abstract class DictionaryAssetBase<TKey, TValue> : ScriptableObject
{
    Dictionary<TKey, TValue> dictionary = null;

    void OnDisable()
    {
        if( dictionary != null )
        {
            dictionary.Clear();
        }
    }

    public TValue this[TKey key]
    {
        get
        {
            if( dictionary != null )
            {
                TValue value;
                if( dictionary.TryGetValue( key, out value ) )
                {
                    return value;
                }
            }

            return default(TValue);
        }

        set
        {
            if( dictionary == null )
            {
                dictionary = new Dictionary<TKey, TValue>();
            }

            dictionary[key] = value;
        }
    }
}

Then for example, a dictionary with byte keys and bool values:-

public class ByteBoolDictionaryAsset : DictionaryAssetBase<byte, bool>
{
}

The only part I left out here is some code for listing the entries currently in the dictionary, used by another custom editor I added for debugging while the game is running in the Unity editor.

A dictionary is used in much the same way as a ScriptableObject variable:-

public class Assigner : MonoBehaviour
{
    [SerializeField] byte thisPlayersID;
    [SerializeField] ByteBoolDictionaryAsset isThingAboutPlayerTrueVar;

    void PlayerThingBecomesTrue()
    {
        isThingAboutPlayerTrueVar[thisPlayersID] = true;
    }
}

public class Watcher : MonoBehaviour
{
    [SerializeField] byte thisPlayersID;
    [SerializeField] ByteBoolDictionaryAsset isThingAboutPlayerTrueVar;

    void Update()
    {
        PollPlayerThingTruthiness();
    }

    void PollPlayerThingTruthiness()
    {
        Debug.Log( "Thing is currently " + isThingAboutPlayerTrueVar[thisPlayersID] + ", about player with ID: " + thisPlayersID );
    }
}

Replacing Singletons

The game has many self contained code modules providing utilities and functionality used by other parts of the code.  Previously these were either static classes or singleton MonoBehaviours, both having their disadvantages:-

  • Static classes can’t have variables serialized by Unity or edited in the inspector.
  • Singleton MonoBehaviours need to live on a GameObject somewhere in the scene (or at least in a prefab).

So now I’ve re-implemented most of these as ScriptableObjects which have neither of these downsides.  They work well with the new ScriptableObject events too, these modules being able subscribe to or raise events, which helps with code decoupling.

Other Uses of ScriptableObjects

I found many more places to use ScriptableObjects, far too many to go over in detail now, but here’s a brief summary of a few of them:-

  • Added ScriptableObject “delegate objects”, making use of the strategy pattern where different variations on a theme implement a common interface.  For example I use this for the procedural generation code for the various different re-sizable parts in the game.
  • Replaced some enums with ScriptableObject assets.
  • Implemented ScriptableObject data assets with built in functionality for better separation of concerns.  For example, I implemented a “sound asset” ScriptableObject that handles random AudioClip selection and playback, and then created a whole bunch of these assets for all the sounds in the game.

New material tool, and a new year!

Hey all, hope everyone has had a good holiday break.  I thought I’d give a quick update on what I’ve been working on over the past few weeks.

Toolbox code refactoring

Up until now, the code for the various tools (builder, linker, painter, etc.) was pretty much all in one (very large) source file.  This was driving me crazy as made it a real pain to to fix bugs, or add new features.  So I finally took some time to do something I’d been wanting to do for ages, which was to refactor this monolithic beast into separate source files for each tool.

There are still things I’d like to improve and clean up (further code decoupling, mainly), but it’s much better than it was, and makes it easier to add new tools, on which subject…

Material swapper tool

After the refactoring, I started work on a new tool that allows you to swap the material on certain parts (such as beams and plates) after they’ve been spawned, and even after they’re already part of a construction.

The first step was to add a material definition that encapsulates all the various part material properties (i.e. the rendering & physics materials, density, strength, and “is it paintable”).  Next I had to refactor the part descriptor code to allow parts to use this new material definition (seems like I’ve been doing a lot of code refactoring lately!)

image

Then on to the material tool itself, which I’m still in the middle of building.  Right now I have a first pass implementation working, with the basic UI done, and the ability to change material on the highlighted part.  There’s still more to do however; for example, save / load (including converting old save files to the new material swappable parts), and probably more refactoring as I’m not quite happy with how the part descriptor code is structured just yet.

Anyway, it shouldn’t take too much longer to finish up, once it’s done I’ll reveal more about how it works.  After that I’ll probably get back to finishing up the linker tool, as that’s been on the back burner for way too long now.

In the meantime, I’d like to say a big thank you for following my progress, particularly to those of you that have been following for a long time, and who continue to play the demo and give me feedback.  I know development of the game is frustratingly slow, but I will get it done eventually, I hope!

Happy New Year, and all the best for 2019.

Damage is done

Well, it took me long enough, but finally the damage system is complete!  Most of the time was actually spent doing optimisation work, which I’ve discussed before in previous posts, the damage system itself didn’t take that long to do.

On the idea scrapheap

My original idea for damage was that each attachment between parts (fixed, rotary, linear, etc.) would have a “health” value.  Then upon a collision contact with a part, some damage amount would be propagated out to all of that part’s attachments.  For each attachment, damage would effectively accumulate over time as its health value gradually reduced, until it reached zero at which point the attachment would be deleted.

However, there were problems with this method:-

  • Deleting individual attachments due to damage would lead to inter-penetration issues, just like when you manually delete attachments with the builder tool.
  • Each attachment having a health value would need to be conveyed somehow to the player via a UI, and I couldn’t think of a way which wouldn’t be messy and confusing.
  • Because damage is applied for every collision contact (of which there can be many), the code is quite performance sensitive, and so needs to be as lightweight and simple as possible, which this method wasn’t.

Binary break

So in the end I went with a simpler solution that just uses a “strength” threshold.  When a part receives a collision contact, I simply compare the impact force with the part’s strength value, and if the force is greater than this value, I break the part off (i.e. delete all of its attachments), otherwise I leave it attached.  In other words, a part is either entirely broken off or it isn’t, there’s no intermediate damage state or health values to deal with.

Happily, I found was that there was not really any need to explicitly propagate the damage force to neighbouring parts to achieve a convincing effect.  Direct impacts seem to be enough, I think because as parts break off they hit other parts and the damage sort of propagates organically.

I’ve also finished the implementation of explosives that integrates with the same damage system, in this case the damage force is simply derived from a linear fall off from the explosion centre.  The resultant bits that are broken off then have an explosion force applied to them to push them around, seems to work pretty well.

Lastly, I’ve also added a per-construction setting to enable / disable invulnerability (i.e. immunity from part breakage), as sometimes it could be useful to disable damage for those particularly “experimental” constructions that might try and smash themselves to bits.

Still to do

As I mentioned, each part has a strength value which basically determines how hard it is to break off.  A part’s strength value is intended to reflect the material it’s made from (e.g. steel is stronger than wood or plastic), and I still need to fine tune these strength values to get the balance correct and hopefully give a nice trade off between the various materials.

Also, I’m thinking I might bias each part’s strength value slightly based on the number of attachments it has, so that the more other parts it’s attached to, the harder it is to break off.  Again, hopefully giving the player further interesting trade offs to choose between when building their constructions.

Yet more optimisations

OK, it seems I spoke too soon when I said in the last blog post that I was done with optimisations to the construction modification code!  When working on the damage system, I found that detaching parts off large constructions with lots of parts could still be really slow, so over the last few weeks I’ve been working to resolve this.

Setting transform parents

When modifying a construction (i.e. attaching or detaching parts), I need to change transform parents in order to manipulate the construction’s transform hierarchy, and by far the biggest performance cost I found was with this re-parenting.  Even when setting worldPositionStays to false when calling SetParent() so that Unity doesn’t have to recalculate world transforms, it’s still really slow when you call SetParent() a lot, due to Unity internally updating the physics colliders.  When modifying a large construction, in the profiler I was seeing Physics.HandleColliderHierarchyChanges and Physics.SyncColliderTransform costing many tens, sometimes hundreds of ms!

So now I’ve done everything I can to get rid of unnecessary re-parenting, thereby minimising the number of SetParent() calls, specifically:-

  • When fixedly attaching parts together, all the parts have to be re-parented from their current rigidbodies to a single rigidbody.  Now, parts from the rigidbody with the smaller number of parts always get re-parented to the rigidbody with the larger number (without re-parenting the larger number of parts).
  • Similarly, when deleting fixed attachments, parts need to be re-parented to separate rigidbodies.  Now, after determining the groupings of parts left after attachment deletion, the largest group always stays under their original rigidbody, and the rest get re-parented to other new rigidbodies.
  • Lastly; I was parenting rigidbodies that were part of the same construction to a container gameobject, this was handy for clarity and debugging purposes, but not strictly necessary.  I changed the code to maintain the rigidbody-to-parent-construction relationship a different way, rather than relying on the transform hierarchy for this.  After that I was able to eliminate setting of the rigidbodies transform parents entirely.

Other optimisations

I was using List<T> to hold temporary lists of parts and rigidbodies when determining how to reorganise a construction hierarchy after deleting attachments.  If there were a large number of things in these lists (e.g. parts), then calling Contains() or Remove() on them would be noticeably slow because these are O(n) operations (a linear search).  So I switched over to using a HashSet<T> instead, for which these operations are O(1).

After a construction is modified, its rigidbodies bounds and mass properties (e.g. centre of mass, inertia tensor, etc.) need to be recalculated.  I’ve now optimised the code that does this, mostly by caching data that doesn’t change (e.g. for parts that haven’t been re-parented to a new rigidbody).

Also after a construction is modified, a few GetComponentsInChildren() calls were being used to cache references to rigidbodies and parts.  These calls were quite slow (and also caused some pretty sizable GC allocs), but after restructuring the code a bit, I was able to eliminate the need for them.

Results

All of these optimisations added together have made huge gains, at least in the test case I was using (a construction with over 2000 parts).  It used to be that detaching a single part in this test could take well over 300ms(!) which caused a noticeable frame rate hitch, now it takes less than 37ms.

Around 22ms of this remaining time is taken by updating rigidbody mass properties (assigning to mass, centerOfMass, inertiaTensor, and intertiaTensorRotation), which there’s not much I can do about.  I can’t understand why this would be so slow, something odd seems to be happening under the hood in Unity.  Maybe this issue is fixed in Unity 2018, but for now I’m stuck on 2017.4, due to the Networking API issues I’ve discussed in previous posts.  Another 12ms out of the ~37ms total is taken by Unity in Physics.UpdateBodies, which I don’t think I can do anything about either unfortunately.

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!)

image

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.

Optimisations and explosions

As I’ve alluded to in previous updates, the damage system is still a way off from completion, so that’s what I’ve been working towards over the last month or so.  One challenge is to design a system to propagate and accumulate damage in a way that is, if not realistic, at least plausible, as well as making sense to the player (without being frustrating or annoying).

Before I can get to this though, there is a more fundamental problem.  Breaking parts off a construction due to damage requires efficient construction modification code, and the existing system just isn’t fast enough.

UI Optimisations

The first problem I looked at was with the construction list in the world tool UI.  Whenever a construction is created or destroyed, this list in the world tool UI gets updated accordingly.  When a part gets broken off a construction, it’s re-parented under its own new construction GameObject, and this process was getting slowed down by the world tool UI being updated.

So now the UI elements in this construction list are held in a pre-allocated pool and used / reused as needed, which avoids the performance cost and GC alloc of instantiation when a new entry is added.  Also, the UI update code now queues up any new constructions and only adds one element to the UI per frame, this results in a slight visible delay as the player sees the UI updating itself, but avoids a single frame performance spike.  In fact I made these changes to all other UI screens too that have a large list of entries (for example, the saved game screens).

Construction modification code optimisations

I’ve now also optimised the construction modification code (actually I had to completely restructure it) to be simpler and more efficient.  It now uses fewer server-to-client RPC calls, only one per player operation (operations being things like attaching a part, deleting an attachment, etc.)  There are less GC allocs too, as it now reuses many of the temporary data buffers these operations require.

These changes so far have made a big difference.  I hacked in a key so I can trigger the deletion of all attachments in a construction for testing purposes, as you can see in the example below.  In this example the cost of breaking the attachments went from around 60ms to less than 25ms on my machine, still a significant performance spike, but definitely moving in the right direction.

image

The major remaining performance cost is with instantiating new construction GameObjects, and also the Rigidbody GameObjects that live under them (as I mentioned before, parts get re-parented to these when they’re broken off an existing construction).  So, just like with the UI elements, to solve this I’m going to need pre-allocated pools of these GameObjects.  However before I do this, to make life simpler, I need to remove all references to Unity networking stuff from the constructions.  Which brings me to another issue…

Unity networking API woes

GearBlocks is still using the old RakNet based Unity networking API, which has been deprecated for a while (and now completely removed from Unity 2018.2).  I was waiting for Unity’s replacement for it – UNET, to be a bit more mature before I switched to it, but sadly UNET has now also been deprecated.  Apparently there’s another replacement solution coming at some point
in the future.  Anyway, I guess it’s a good thing I never switched to UNET, it will be supported for another couple of years I believe, but there doesn’t seem much point using it now.  So the upshot is, I’m probably going to have to look for a third party solution.

Whatever networking solution I end up using, one thing is for sure, I really need to abstract the networking API away from the rest of the GearBlocks code as much possible.  This is something I should have done in the first place really, it’ll make changing networking APIs much easier in the future.

So to allow for pooled construction GameObjects, and as a first step towards this abstraction, I’ve now implemented my own world object ID system.  This allows GameObjects to have a unique ID consistent across the server and all the clients, and is now used by construction and part GameObjects.  This allowed me to remove the Unity NetworkView from the construction GameObject (which will make pooling them easier), and move all code for state synchronisation out of the construction and into a central manager that synchronises the state of all constructions together.

The next step in this abstraction effort will be to wrap all the RPC calls (currently scattered throughout the code) behind another interface.  As well as meaning there will then only be one place in the code to modify when I change networking APIs, it will also allow me to remove the NetworkView from part GameObjects too.

Explosives go boom

My future plans for GearBlocks mean that the damage system needs to apply damage not only from collision impacts, but also from explosives.  So I had some fun adding a simple placeholder explosive that’ll serve as a good test for now.  Right now it only applies a force to nearby objects, it doesn’t do any damage yet, that’s something I’ll have to work on soon!

image