All Saving and Loading of Persistent Data related to SAM is initiated via the Component Manager, which automatically ensures component specific data (such as Active Grids and Worlds) is also saved and loaded.
The Component Manager is responsible for choosing what to save. How that date is saved/loaded is under the control of Persistent State Managers, and while a default version of one of these Managers is included with the Streamable Assets Manager, it is likely you will wish to create a custom Persistent State Manager that integrates with an existing Save/Load solution.
We invite you to learn more about Persistent State Managers via their dedicated chapter; this Component Manager Section will instead focus on saving/loading in the context of the Component Manager only.
Learn About Persistent State Managers
You are free to perform a save operation at any time after the Component Manager has completed initialization without errors.
Saves are performed by calling the ComponentManager.Save method, which takes in an IPersistentStateManager object (which again, is responsible for deciding how the data is saved).
Saves are performed in a single frame and shouldn't take up much time, however the time and amount of data that needs to be saved will be greater the more Active Grids and Worlds you are using.
Data for Inspector Created Active Grids and Worlds is always saved so long as those components have not been destroyed. Data for Runtime Created Active Grids and Worlds is only saved if persistent versions of those components were created and the components have not been destroyed. Upon load, these Runtime Created Persistent Components are automatically recreated by the Component Manager using the IDs of the prototypes they were constructed from.
When Inspector Created Active Grids and Worlds are destroyed, the Component Manager makes note of it so that upon loading of the data, they can be destroyed again.
The tracking of created and destroyed components allows the true state of the Streamable Assets Manager to be maintained between saving and loading the game.
Load operations should be performed just after loading the scene containing your Component Manager, but before the Component Manager has been initialized..
Loads should be performed by calling the ComponentManager.Load method, which takes in an IPersistentStateManager object (which again, is responsible for deciding how the data is loaded).
Loads are performed in a single frame and shouldn't take up much time, however the time will be greater the more Active Grids and Worlds you are using.
Data for Inspector Created Active Grids and Worlds is always loaded so long as those components were not destroyed at the time of the data being saved. Data for Runtime Created Active Grids and Worlds is only loaded if persistent versions of those components were created and the components still existed at the time of saving. These Runtime Created Persistent Components are automatically recreated by the Component Manager, which is possible through the use of Prototypes.
When Inspector Created Active Grids and Worlds are destroyed, the Component Manager makes note of it so that upon loading of the data, they can be destroyed again.
The tracking of created and destroyed components allows the true state of the Streamable Assets Manager to be maintained between saving and loading the game.
If you have persistent data that was saved with the previous save system - for instance perhaps you have a shipped game that used a Persistent Data Controller from the Terrain Slicing & Dynamic Loading Kit - that data will be in a form that is no longer compatible with the new save/load system. DO NOT FEAR, HOWEVER!
If you have existing save data you need loaded that cannot be loaded using the Persistent State Manager, you can use one of the static conversion methods on the Component Manager to load the data and re-save it using your Persistent State Manager.
There are two such methods available, both of which are named ConvertOldSaveData, the only difference between the two is that one takes a PersistentDataController object (use if you saved the data using a PersistentDataController before via the ComponentManager's Save method), while the other takes a string object (use if you saved the data as a string via the Component Manager's GetSaveData method).
These methods require a valid Component Manager instance, which should be an upgraded Component Manager with the same ID as the previous Component Manager used to save the data.
Some data related to Active Grid sizes is no longer used with the addition of Loading Blueprints, however you may wish to use this data to choose a Loading Blueprint that best matches the size of the Active Grid as stored in the old data. In such cases, the conversion methods output this data in list form, with each entry in the list referring to a specific Active Grid. You can iterate through this list and choose a Loading Blueprint for each Active Grid, then use the ActiveGrid.PreInitialize_SetLoadingBlueprint(ByName, ByID, or ByIndex) to set the Active Grid Base Grouping to use that Blueprint.
Once you have successfully converted the data, you can delete the old data. Since conversion should only happen once, you can use the presence of the old data as a means of testing whether conversion is necessary.
The conversion methods work by loading the old save data, then re-saving that data using a Persistent State Manager. As such, a valid Persistent State Manager that is ready to save data is required to make use of the conversion methods.
Learn About Persistent State Managers
See ConvertOldData Method in API
--Special Note--
In the previous data saving solution, the index of each Prototype was saved with persistent data and used to reconstruct Persistent, Runtime created Active Grids and Worlds. With Persistent State Managers, the ID of each Prototype is used instead, which offers greater flexibility in re-ordering and removing Prototypes. Because of this, please note the following:
1) All Prototypes of the same Component Type (Active Grid or World) must have unique IDs.
2) The order of the Prototypes must be the same as the order of the Prototypes when the old save data was saved. This is necessary for the conversion method to correctly match the prototypes in the old data. If you do not need to convert data, the order of the Prototypes does not matter; only that the IDs of the prototypes remain the same for the lifetime of your Application.