Game maintenance

The snapshot service is in alpha and the deployment service is in beta, and they may have breaking changes before stabilizing. For more information on maturity stages see Maturity stages.


Running regular scheduled maintenance on a game world is a common task when you have a deployment running 24 hours a day. Previously the only tools to do this were the SpatialOS CLI and the Console (see Scheduled maintenance). Now you can write your own automated script using the Platform SDK.

In this scenario you'll need an active running deployment to start with, and you'll end with a different active running deployment. For this example we're setting up the first deployment with Setup() and stopping the second deployment with Cleanup().

Find out how to download the Platform SDK from the setup guide.

You can find the full code example for this scenario on GitHub.

Example: setting up game maintenance for a deployment

1. Instantiate clients

Instantiate clients of the DeploymentServiceClient and SnapshotServiceClient types.

Use the Create method of the DeploymentServiceClient and SnapshotServiceClient.

private static readonly DeploymentServiceClient DeploymentServiceClient = DeploymentServiceClient.Create();
private static readonly SnapshotServiceClient SnapshotServiceClient = SnapshotServiceClient.Create();

By default, it uses your refresh token saved locally by the SpatialOS CLI:

  • Windows: C:\Users\<username>\AppData\Local\.improbable\oauth2\oauth2_refresh_token\
  • Mac: ~/.improbable/oauth2/oauth2_refresh_token

If you want to provide a refresh token, you can instantiate a PlatformRefreshTokenCredential object and supply it to create:

var credentialsWithProvidedToken = new PlatformRefreshTokenCredential("my_refresh_token");
private static readonly DeploymentServiceClient DeploymentServiceClient = DeploymentServiceClient.Create(credentials: credentialsWithProvidedToken);
private static readonly SnapshotServiceClient SnapshotServiceClient = SnapshotServiceClient.Create(credentials: credentialsWithProvidedToken);

Since this example is intended to run as an automated task, we recommend using a service account for authentication. To create a service account, see Service account maintenance.

2. Get your running deployment

You need to use the cloud project name and deployment name

Retrieve the first deployment entry in the returned list that has the status Running:

var currentLiveDeployment = DeploymentServiceClient.GetRunningDeploymentByName(new GetRunningDeploymentByNameRequest
	ProjectName = ProjectName,
	DeploymentName = DeploymentName,

3. Remove my_live_tag and mark deployment as in maintenance

You can use deployment tags to identify attributes like environment (such as production or testing) or whether a deployment is part of the live game. In this case, we're removing the tag my_live_tag to indicate that this is no longer a live deployment and players should not be directed towards it:

var setTagsRequest = new SetDeploymentTagsRequest
	DeploymentId = currentLiveDeployment.Deployment.Id,
	Tags = {currentLiveDeployment.Deployment.Tags},

Next, set the worker flags to have a maintenance value of true or any other pairs of your choosing for a particular worker type. This lets all workers of that type in the deployment know that the deployment is entering maintenance mode and they should stop performing game updates. Send that update with a call to UpdateDeployment:

currentLiveDeployment.Deployment.WorkerFlags.Add(new WorkerFlag
	Key = "maintenance",
	Value = "true",
	WorkerType = "unity"
var setFlagsRequest = new SetDeploymentWorkerFlagsRequest
	DeploymentId = currentLiveDeployment.Deployment.Id,
	WorkerFlags = {currentLiveDeployment.Deployment.WorkerFlags},

4. Take a snapshot of the currently running game

This can take some time, so use the PollUntilCompleted method and wait until it's completed:

var latestSnapshot = SnapshotServiceClient.TakeSnapshot(new TakeSnapshotRequest
	Snapshot = new Snapshot
		ProjectName = currentLiveDeployment.Deployment.ProjectName,
		DeploymentName = currentLiveDeployment.Deployment.DeploymentName

5. Stop the deployment using its ID and the cloud project name

DeploymentServiceClient.DeleteDeployment(new DeleteDeploymentRequest
	Id = currentLiveDeployment.Deployment.Id,

The ID is a universally unique identifier for a particular run of a deployment.

6. Reuse the latest snapshot from the old deployment to start a new deployment

After cloning the deployment object, set the ID of the snapshot that was previously taken to restart at the same game state. All deployment tags and worker flags are cleared before starting the deployment to start with a clean slate. Once the deployment is up and running it can then be updated with the live tag.

 var newDeployment = DeploymentServiceClient.CreateDeployment(new CreateDeploymentRequest
	DeploymentName = currentLiveDeployment.Deployment.DeploymentName,
	ProjectName = currentLiveDeployment.Deployment.ProjectName,
	RuntimeVersion = currentLiveDeployment.Deployment.RuntimeVersion,
	StartingSnapshotId = latestSnapshot.Id,

var setLiveTagsRequest = new SetDeploymentTagsRequest
	DeploymentId = newDeployment.Id,

You may also choose to edit the snapshot before restarting your deployment. You can do this by converting the snapshot to text and back by running spatial project history snapshot convert. You can then upload the snapshot and use it to create the new deployment.

Updated about a year ago

Game maintenance

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.