This website uses cookies to improve our services and deliver relevant ads.
By interacting with this site, you agree to this use. For more information, see our Cookies Policy
Seamlessly save, synchronize, and load data between devices and installs using our Cloud Storage service.
Cloud Storage is designed to support the following use-cases:
Storage Formats
The Cloud Storage service uses buckets (directories) and blobs (files), indexed by a key (file name), to store data. The number of blobs stored per Bucket can not exceed 10,000. However, apps should use a smaller limit for the number of blobs, as the resources required to process a large number of keys may impact the user’s experience.
Direct file storage is not supported.
Cloud Storage is divided into buckets (directories) of data that are configured in the Developer Center, under the Cloud Storage tab. Apps may define more than one bucket for multiple save types or data.
For example, when creating a new save you would call ovr_CloudStorage_Save(bucket_name, key, data_pointer, data_size, counter, extra_data). More details can be found in the ovr_CloudStorage_Save reference.
In the Cloud Storage tab of the Developer Center click the Create Cloud Storage Bucket button and enter the information about the bucket that you would like to create.
Bucket names must to conform to the Microsoft Windows directory name restrictions (https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx), are case-insensitive, must be unique within an Application Grouping, and less than 128 characters. Buckets do not exist by default for an application, to enable Cloud Storage at least one must be created on the dashboard.
Information about conflict management strategies can be found below in the Managing Conflicts section below.
Once you've defined the Cloud Storage buckets, you can integrate the service into your game. When calling the methods listed below you'll reference the bucket_name you created for the bucket.
The following is the typical Cloud Storage lifecycle:
The following SDK methods can be called from your client app:
Save a blob:
Native - ovr_CloudStorage_Save()
Unity - Platform.CloudStorage.Save()
Data is stored as an opaque binary blob, review the ovr_CloudStorage_Save page for information about the parameters and return data structure.
This call sends the blob data to the locally running Oculus process and will not trigger network calls. Network synchronization happens when the App is no longer running. Total size for a blob can not exceed 10Mb.
Load a blob:
Native - ovr_CloudStorage_Load()
Unity - Platform.CloudStorage.Load()
Data is stored as an opaque binary blob, review the ovr_CloudStorage_Load page for information about the parameters and return data structure.
If the bucket is configured for manual conflict resolution and a conflict exists between the local and remote versions, the load call will return an error. The process to resolve conflicts is discussed below. Loading a blob will not initiate a network call.
Delete a blob:
Native - ovr_CloudStorage_Delete()
Unity - Platform.CloudStorage.Delete()
Data is stored as an opaque binary Blob, review the ovr_CloudStorage_Delete page for information about the parameters and return data structure.
This will delete both the cloud and local copies of the blob. You may write new data to a deleted blob without waiting for synchronization.
Find a blob:
You may want to retrieve some information about the available blobs to determine which one to load. The following methods allow you to retrieve the metadata for one or all saved data blobs.
Retrieve blob metadata for all blobs:
Native - ovr_CloudStorage_LoadBucketMetadata(bucket_name)
Unity - Platform.CloudStorage.LoadBucketMetadata(bucket_name)
Review the ovr_CloudStorage_LoadBucketMetadata page for information about the parameters and return data structure.
Retrieve blob metadata for a specific blob:
Native - ovr_CloudStorage_LoadMetadata(bucket_name, key)
Unity - Platform.CloudStorage.LoadMetadata(bucket_name, key)
Review the ovr_CloudStorage_LoadMetadata page for information about the parameters and return data structure.
Blob Metadata
Both of the metadata SDK methods will return results in the same format containing information you can use to determine which save you want to use or load.
The response payload will be in a format similar to the following:
uint32 data_size = ovr_CloudStorageMetadata_getDataSize(metadataHandle) uint64 saved_time = ovr_CloudStorageMetadata_getSaveTime(metadataHandle) int64 counter = ovr_CloudStorageMetadata_getCounter(metadataHandle) const char* extra_data = ovr_CloudStorageMetadata_getExtraData(metadataHandle) ovrCloudStorageVersionHandle handle = ovr_CloudStorageMetadata_getHandle(metadataHandle) ovrCloudStorageDataStatus status = ovr_CloudStorageMetadata_getStatus(metadataHandle)
The Cloud Storage service supports synchronizing data between multiple devices and platforms. This requires a conflict resolution strategy to handle situations where multiple devices may upload blobs to the same key. This situation is common on mobile devices but can occur between PCs as well. The following resolution strategies are available:
Latest Timestamp
Resolving the conflict by using the latest timestamp is the least complex resolution. It configures the bucket to prefer the blob that has the timestamp recorded most recently by the local device. A timestamp is recorded at the time the call to ovr_CloudStorage_Save() is made. Client blobs with timestamps earlier than the remotely stored version are discarded.
Highest Counter
Buckets configured with the highest counter method will prefer blobs with the highest value set in the counter field. This method could be used if you wanted to preserve the blob with the highest score. Blobs stored with the same counter value as a remote version will attempt to be stored. However, multiple devices doing this represent a race-condition where either device may win.
Manual
You may also choose to handle conflict resolution entirely in your app. When an app saves a new local blob to a specific key that's in state ovrCloudStorageDataStatus_InConflict, the blob will not be uploaded until the app resolves the conflict. Conflict resolution can be done at any time but it's best done during App startup and shutdown. The need for manual conflict resolution can be detected by checking the metadata status, or by reviewing the save message response.
ovrCloudStorageUpdateResponseHandle response = ovr_Message_GetCloudStorageUpdateResponse(save_message)
ovrCloudStorageUpdateStatus status = ovr_CloudStorageUpdateResponse_GetStatus(response))
if (status == ovrCloudStorageUpdateStatus_ManualMergeRequired) { // perform manual merge... }The first step to resolving is to load the metadata for the conflicting blobs:
ovr_CloudStorage_LoadConflictMetadata(bucket, key)
This is an asynchronous call and the response message is parsed to get the metadata:
ovrCloudStorageConflictMetadataHandle response = ovr_Message_GetCloudStorageConflictMetadata(message) ovrCloudStorageMetadataHandle local_metadata = ovr_CloudStorageConflictMetadata_GetLocal(response) ovrCloudStorageMetadataHandle remote_metadata = ovr_CloudStorageConflictMetadata_GetRemote(response)
Resolving based on metadata
If the metadata for the blob contains enough information to resolve the conflict, then the next step is to call:
ovr_CloudStorage_ResolveKeepRemote(bucket_name, key, remote_handle)
to choose the remote blob, or:
ovr_CloudStorage_ResolveKeepLocal(bucket_name, key, remote_handle)
to choose the local blob. The handle from the remote blob's metadata is passed in to prevent data loss in the instance that a new remote blob appears during conflict resolution.
Resolving by inspecting data
If you need to inspect the data blobs to determine which to keep, they can be loaded using the handle from the metadata:
ovr_CloudStorage_LoadHandle(handle)
This works for both the local and remote handles. If the remote blob has not been cached locally, requesting the remote will initiate a network call to fetch any remaining data.
Resolving by merging the remote and local data
If the app needs to merge the saved blobs, they can be loaded as described above, then the app can save a new local version and resolve by choosing that:
ovr_CloudStorage_Save(bucket_name, key, merged_data_pointer, merged_data_size, counter, extra_data) ovr_CloudStorage_ResolveKeepLocal(bucket_name, key, remote_handle)
The CloudStorageSample Unity app provided in the Platform SDK download demonstrates using the Cloud Storage service to save multiple records and perform conflict resolution. Please see the Sample Apps page for more information about the apps that are available.