• Installation Guide
  • Amoebot Model
  • User Guide
  • Model Reference
  • Dev Guide
  • API Documentation
Search Results for

    Show / Hide Table of Contents
    • Architecture Overview
    • Simulator
      • History
      • Save and Load
      • User API
      • Round Simulation
      • Reflection
      • Error Handling
    • User Interface
    • Input Handling
    • Render System
      • Unity Rendering Basics
      • Background Renderer
      • UI Renderer
      • Object Renderer
      • Particle Renderer
        • Particles
        • Shader Example
        • Circuits and Bonds
        • Data Structures and Interface

    Developer Guide: Save and Load

    Being able to save a simulation state and run it later with an updated algorithm can be a very useful feature for developing amoebot algorithms. AmoebotSim 2.0 provides two different ways of saving and loading states: In Initialization Mode, you can save the current system configuration, including all particle parameters, and load any saved configuration to easily reuse it for multiple simulation runs. In Simulation Mode, you can even store the entire simulation history up to the current round, allowing you to review and replay scenarios in which problems occurred, for example. This page explains how the Save and Load feature is implemented.

    Format

    The basic idea of the Save and Load feature is to use Unity's built-in JSON utility, which allows serializable objects to be easily translated to and from the textual JSON format. We can store the JSON content in simple text files which the user can select through a file browser.

    The main challenge of implementing this feature is representing the simulation and initialization state in a serializable format. To this end, we define additional classes that "mirror" the original classes by storing their relevant data while being simple enough that they can be serialized.

    !Serialization

    Implementation

    A type is serializable by Unity's JSON utility if it is a primitive type or if its members are serializable or lists/arrays of serializable types. We mark a type as serializable by giving it the Serializable attribute:

    [Serializable]
    public class MySerializableType {
        public int member1;
        public float member2;
        public bool[] member3;
        public MyOtherSerializableType member4;
        ...
    }
    

    The JSON utility recursively translates a serializable type into text. This does not work for recursive data types, so we need to avoid using such types. See this page for all serialization rules.

    Making the system classes that represent the simulation and initialization states serializable is not possible because their data is too complex. It is also a bad idea because they often store the same data in multiple ways for optimized access, making the save data unnecessarily large. Thus, we define new classes that store the data in a simplified and serializable format instead.

    Every class whose state should be saved in a file defines a GenerateSaveData() and an InitializeFromSaveData(...) method (or similar). The first method returns a serializable representation of the object's state and the second method updates the object's state to match the data in the given serializable object. For example, the Particle class uses the ParticleStateSaveData class as its serializable representation, working with the GenerateSaveData and CreateFromSaveState methods.

    Because serializable types can be nested, as explained above, we can define the serializable mirror classes as a hierarchy similar to that of the original classes. At the top of this hierarchy are the SimulationStateSaveData and the InitializationStateSaveData classes, representing the Simulation Mode state and the Initialization Mode state, respectively. When the GenerateSaveData() method is called on one of the original classes, it forwards the call to its subordinate classes to construct its own mirror object using the mirror objects of its constituents. For example, every object that stores a history uses the ValueHistory class or one of its derivatives, which in turn uses the ValueHistorySaveData class (or one of its derivatives) as its serializable representation.

    One notable combination of two features is the PinConfigurationSaveData class. Because it is a very compact and simple representation of the complex pin configuration data, it is also used by the ValueHistoryPinConfiguration class, which uses the small representation internally to minimize the memory usage and bookkeeping effort of the history.

    Finally, to select the files for storing and loading the save data, the FileBrowser class defines several methods for choosing files of a specific type. Although all save data is stored in the textual JSON format, we use different file extensions to differentiate between the types: *.amalgo files store simulation state data and *.aminit files store initialization state data.

    In this article
    Back to top AmoebotSim 2.0 Documentation v1.11
    Copyright © 2025 AmoebotSim 2.0 Authors
    Generated by DocFX