Try SpatialOS

Sites

Menu
These are the docs for 12.2, an old version of SpatialOS. 13.2 is the newest →

Manipulating snapshots

All code examples in this section assume using Improbable.Worker; and using Example; (the generated code namespace).

The SDK provides two classes in to manipulate snapshots stored in files:

This lets you write tools to perform offline transformations of the simulation state, or to programmatically create the starting point of a simulation.

Snapshot manipulation does not require a Connection, making it possible to develop standalone, offline snapshot manipulation tools. However, we recommend using the build infrastructure provided by SpatialOS for workers to build your standalone tools.

These stream classes are the recommended methods of manipulating snapshots as they do not require the entire snapshot to be stored in memory when reading or writing a snapshot.

SnapshotInputStream

SnapshotInputStream has a constructor and three public methods:

// Constructs a SnapshotInputStream to read the file at the given string path.
public SnapshotInputStream(string path)

// Releases the resources of the SnapshotInputStream.
public void Dispose()

// Reads the next EntityId entityId, Entity entity pair from the snapshot.
// Returns an optional string error message if an error occurs during reading.
public Option<string> ReadEntity(out EntityId entityId, out Entity entity)

// Returns true if the SnapshotInputStream has not reached the end of the snapshot.
public bool HasNext();

SnapshotOutputStream

SnapshotOutputStream has a constructor and two public methods:

// Construct a SnapshotOutputStream to write a snapshot to a file at the string path.
public SnapshotOutputStream(string path)

// Writes the end of snapshot header and releases the resources of the SnapshotOutputStream.
public void Dispose()

// Writes the (EntityId entityId, Entity entity) pair to the snapshot.
// Returns an Optional string error message if an error occurs during writing.
public Option<string> WriteEntity(EntityId entityId, Entity entity)

Example

The assemblies that contain the generated code for the components present in the snapshots your program manipulates must be loaded (not just referenced); otherwise, the SDK will report “undefined component ID” errors.

These assemblies are loaded automatically whenever your program uses any class defined in them, but if this is not the case, you can manually load them using the Assembly.Load() method.

Here is an example of loading a snapshot, performing some manipulation on it, and saving it back. It uses the types and components defined in the example from Generated code.

public static void AddLowHealthEffectToEntities(string snapshotFilename, string newSnapshotFilename)
{
  // Open a SnapshotInputStream to read from the snapshot file saved at snapshotFilename.
  SnapshotInputStream inputStream = new SnapshotInputStream(snapshotFilename);
  // Open a SnapshotOutputStream to write to a snapshot file at newSnapshotFilename.
  SnapshotOutputStream outputStream = new SnapshotOutputStream(newSnapshotFilename);

  Improbable.EntityId entityId;
  Entity entity;
 
  // Iterate over every entity in the snapshot file.
  while (inputStream.HasNext()) 
  {
    // Read the next (entityId, entity) pair from the snapshot file.
    var errorOpt = inputStream.ReadEntity(out entityId, out entity);
    if (errorOpt.HasValue)
    {
      throw new System.SystemException("Error loading snapshot: " + errorOpt.Value);
    }
    if (entity.Get<Creature>().HasValue)
    {
      var status = entity.Get<Creature>().Value.Get();
      // Add the "LowHealth" effect to all entities that have a Creature component 
      // and less than 10 health points.
      if (status.Value.health < 10)
      {
        status.Value.effects.Add(new StatusEffect("LowHealth", 100));
      }
    }
    // Write the (entityId, entity) pair to the snapshot file.
    errorOpt = outputStream.WriteEntity(entityId, entity);
    if (errorOpt.HasValue)
    {
      throw new System.SystemException("Error saving snapshot: " + errorOpt.Value);
    }
  }
  // Dispose of the inputStream to release the stream's resources.
  inputStream.Dispose();
  // Dispose of the outputStream to write the end of the Snapshot and release the stream's 
  // resources.
  outputStream.Dispose();
}

Search results

Was this page helpful?

Thanks for letting us know!

Thanks for your feedback

Need more help? Ask on the forums