It is time for a new piece in our “How To” series that is long overdue. You can find previous installments by clicking on the
how-to label under the title of this thread or by simply clicking on this link. Today’s installment will provide you with a walk-through of the seamless migration of players between deployments. The technical content is this time being provided by Peter Griffin (@peter_g) a member of our internal demo “AAA” team (Yes! That’s the team that created our Survival demo). This how-to is focused on our Unity SDK.
Beam me up Scotty!
Migrating between deployments? What’s that you might think. Why should I use it?
If we take the example of Mavericks the upcoming MMO / Battle Royale mix by Automaton players will enjoy a full social experience within a hub, a large-scale deployment with high player density, and from time to time join intense and epic Battle Royal sessions of 200 to 1000 player which run on dedicated deployments. Another possibility is the classical situation where you have regional deployments to improve latency for your players. Whereas normally this would be a blocker for in-world interactions between geographically separated friends this no longer needs to be the case with SpatialOS: simply add vehicles for fast travel (ship, plane, spacecraft, broomstick, …) to your game and have players use those to pass the swatches of your mega-sized world that represent the boundaries between the regional deployments. The whole thing without the need for loading screens or game menus to select other servers.
Maintaining simultaneous connections
Now for the technical implementation in Unity. Our standard Unity SDK only supports a single connection model. Hence we will need to make some modifications to the SDK in order to get our idea working, luckily for you the source code of the SDK is available and you are free to clone and modify it!
The bootstrap of the connection is typically handed by this code in the Unity SDK. We can reuse this in a straightforward manner to create a
Connect method that will return a SpatialOS connection via our C# SDK.
The goal is to enable the Unity SDK to work with two simultaneous connections and merge the updates received from both. We do this by designating one connection as “primary” and the other as “secondary”. If an entity exists on the primary connection, we discard all updates that we potentially receive via the “secondary” connections: such entities that exist on both deployments are mostly other players that are transitioning as well. For entities that only exist on one deployment there is no conflict and the merge of the received updates is trivial. When switching the “primary” status between the two deployments care should be taken to perform a full hand-off and synchronisation for the transitioning player of any data stored in a third-party service.
We can implement the connection management in a class that wraps the SDK’s and abstracts away the reconciliation logic. Any component updates sent to this class by a worker are multiplexed to all active connections and the updates received on the individual connections are forwarded to the callbacks registered on the class.
With these modifications applied to the SDK we can now look at the larger picture of how they can be used to achieve an actual transition: clue… it works in 4 phases.
For our proof-of-concept we used the example of a border-crossing between the US and the UK. The US side represents a deployment in our US region and the UK side represents a deployment running in our EU region.
Click on this link for some video time to see how it looks both from the in-game and inspector perspectives!
The steps that one can see happen seamlessly in the video above are as follows:
Initially, with the border crossing still out of sight, we are in the usual situation with a single connection to the US deployment.
When the border-crossing comes in sight we list the available deployments via the Locator API. By the use of specific tags on deployments for each region we can then easily identify the one with the
eutag and set up a connection to it via our modified Unity SDK. We keep the US connection marked as the “principal” one for now.
As the player crosses the actual border we make any last player-related updates to third-party services from the primary deployment. We then flip the switch in our modified SDK to mark the EU connection as “principal”. This way we can still observe things happening on the US side but we are relying on the EU connection to keep us up-to-date about other entities moving between the deployments.
Once the border-crossing falls out of sight we no longer need (or even receive) updates about entities on the US deployment and we can safely close down the connection.
NB: If after listing deployments at step 2 we find that the EU one is not available we can show the in-game border-crossing as closed to prevent people from attempting a transition.
That’s All Folks!
By now I hope that you have all the necessary keys to start implementing deployment transitions in your own project. If you have any questions or ideas for improvements do not hesitate to fire them off here below in the thread! Also if you have other thoughts of how such transitions could be used for novel gameplay mechanics share them as well. We’re always keen to hear all the great ideas that our developer community keeps coming up with.