Try SpatialOS




All code examples in this section assume you have defined a MyComponents function as described in Providing components, and set up the following preamble:

#include <improbable/standard_library.h>
#include <improbable/worker.h>
#include <example.h>

using namespace improbable;

The SDK provides two classes 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 has a constructor and two public methods:

/** Creates a SnapshotInputStream to read the snapshot file from the given path. */
explicit SnapshotInputStream(const ComponentRegistry& registry, const std::string& path);

/** Returns true if SnapshotInputStream has not reached EOF. */
bool HasNext();

 * Loads the next EntityId and Entity pair from the Snapshot. Returns an
 * error message if error occurred.
Option<std::string> ReadEntity(EntityId& entity_id, Entity& entity);


SnapshotOutputStream has a constructor and one public method:

/** Creates a SnapshotOutputStream to read the snapshot file from the given path. */
explicit SnapshotOutputStream(const ComponentRegistry& registry, const std::string& path);

 * Writes the EntityId and Entity pair to the output stream. Returns an
 * error message if error occurred.
Option<std::string> WriteEntity(EntityId entity_id, const Entity& entity);

When a SnapshotOutputStream is destructed, the end of file is written and the stream’s resources are released.


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.

worker::Option<std::string> AddLowHealthEffectToEntities(const std::string& snapshot_filename,
                                                         const std::string& new_snapshot_filename) {
  // std::unordered_map<worker::EntityId, worker::Entity> entities;
  // Create a SnapshotInputStream to read from the snapshot file.
  worker::SnapshotInputStream input_stream{MyComponents(), snapshot_filename};
  // Create a SnapshotOutputStream to write to a snapshot file.
  worker::SnapshotOutputStream output_stream{MyComponents(), new_snapshot_filename};

  // Add the "LowHealth" effect to all entities that have a Status component and less than 10 health
  // points.
  while (input_stream.HasNext()) {
    worker::Entity entity;
    worker::EntityId entity_id;
    auto error_or_empty = input_stream.ReadEntity(entity_id, entity);
    if (!error_or_empty.empty()) {
      std::cerr << "Error reading entity from snapshot: " << *error_or_empty << std::endl;
      return error_or_empty;

    auto creature = entity.Get<example::Creature>();
    if (creature && creature->health() < 10) {
      creature->effects().emplace_back("LowHealth", 100);

    // Save entity back to the snapshot file.
    error_or_empty = output_stream.WriteEntity(entity_id, entity);
    if (!error_or_empty.empty()) {
      std::cerr << "Error saving entity to snapshot: " << *error_or_empty << std::endl;
      return error_or_empty;

  return {};

Search results

Was this page helpful?

Thanks for letting us know!

Thanks for your feedback

Need more help? Ask on the forums