The Title Storage Interface enables developers using Epic Online Services (EOS) to retrieve encrypted data from cloud servers. Data that you store through this interface is accessible to any user on any device where they can log in. While similar to the Player Data Storage Interface, this interface is specialized to handle game-specific data rather than user-specific data, and can provide different versions of files based on the user's platform, region, or other conditions. For more specific information about the differences between the Title Storage Interface and the Player Data Storage Interface, see the Differences from Player Data Storage section at the bottom of this document.
To access the Title Storage Interface, acquire an EOS_HTitleStorage
handle through the Platform Interface function, EOS_Platform_GetTitleStorageInterface
. All Title Storage Interface functions require this handle as their first parameter. You must ensure that the EOS_HPlatform
handle is ticking in order for callbacks to trigger when requests are completed.
To use this interface, you must initialize the EOS Platform with the following extra parameters:
-
const char* EncryptionKey
: This 64-character hexadecimal string builds a 256-bit key that EOS uses to encrypt user data. Epic's backend servers do not store this key. If there is no key, calls toEOS_Platform_GetTitleStorageInterface
return a null reference. If the key is not the correct length or format, file-management functions from the Title Storage Interface result in failure and will return theEOS_TitleStorage_EncryptionKeyNotSet
error code. -
const char* CacheDirectory
: This is the full path to the local directory that the interface will use for temporary storage during data file transfers. This could be any location, with the system's temporary directory or the game's data directory being common choices. If the directory you specify does not exist, EOS will attempt to create it. You can use the same directory for multiple users and products, and EOS will ensure that they do not collide. If there are issues with the directory, calls to file-management functions will result in failure and will returnEOS_CacheDirectoryMissing
orEOS_CacheDirectoryInvalid
error codes. Please refer to the EOS Platform documentation for platform-specific limitations on what folders can be used.
File Management
File Name Format
File names in EOS take the following form: Directory0/Directory1/DirectoryN/Filename.Extension
The "Directory" and "Extension" portions are optional. The "/" character must appear after each directory name, but cannot appear anywhere else, including as the first or last character. File names may use the following characters:
- Any alphanumeric ASCII character
!
-
_
+
.
'
(
)
File names may not exceed EOS_TITLESTORAGE_FILENAME_MAX_LENGTH_BYTES
(64) characters.
Querying Files
The EOS SDK enables you to retrieve information about files stored on the cloud through a few querying API calls. Your query will return metadata about one or more files, including each file's name, size (in bytes), and MD5 hash. You can then request and manage your own copy of this metadata, and use it to access or modify the files. Because files are stored in encrypted form on the backend, metadata such as file size and MD5 hash reflects the encrypted file, rather than the original file you uploaded through the Dev Portal.
Be sure to copy any information you may need from the cache during your query's callback function. This data's lifetime is not guaranteed to last beyond the duration of the callback function. This is especially important when running multiple queries, as each successful query can alter the contents of the cache.
Most functions contain an optional Product User ID parameter for better tracking. You can query data with no Product User ID (by passing nullptr instead), but the User ID overrides you set up on the Dev Portal will not be available. Callbacks contain the same User Product ID value you pass
Querying a Single File
If you only need information about a single file, and you know that file's name, you can call EOS_TitleStorage_QueryFile
function, passing in an EOS_TitleStorage_QueryFileOptions
structure initialized as follows:
Property | Value |
---|---|
ApiVersion | EOS_TITLESTORAGE_QUERYFILEOPTIONS_API_LATEST |
LocalUserId | (Optional) The EOS_ProductUserId of the local user who is requesting file data |
Filename | The name of the file you are querying |
When the operation completes, EOS will run your callback (of type EOS_TitleStorage_OnQueryFileCompleteCallback
) with an EOS_TitleStorage_QueryFileCallbackInfo
structure. If the call succeeded, EOS now has data about your file in the cache.
Querying Multiple Files by Tag
To query multiple files at once, or to query files without knowing the exact file names, you must first apply tags to your files through the Dev Portal. The EOS SDK can then query files based on those tags. File tags are strings that use the same formatting rules as EOS file names. When querying files this way, you must provide one or more tags, and the EOS SDK will retrieve a list of all files that contain at least one of the tags. To do this, call EOS_TitleStorage_QueryFileList
with an EOS_TitleStorage_QueryFileListOptions
data structure initialized as follows:
Property | Value |
---|---|
ApiVersion | EOS_TITLESTORAGE_QUERYFILELISTOPTIONS_API_LATEST |
LocalUserId | (Optional) The EOS_ProductUserId of the local user who is requesting file data |
NumTags | The number of tags in the list of tags (has to be positive) |
ListOfTags | The array of tags (ASCII strings) you are querying files for |
Upon completion, EOS will run your callback function (of type EOS_TitleStorage_OnQueryFileListCompleteCallback
) with an EOS_TitleStorage_QueryFileListCallbackInfo
data structure. If the call succeeded, the data structure contains the number of files found, and the information about those files is available in the EOS cache.
Querying All Files
The Title Storage Interface does not provide a specific API call to query all files. However, if you apply a certain tag to every file you upload, you could use EOS_TitleStorage_QueryFileListOptions
with that tag to retrieve data about all of your files.
Examining Cached File Information
Once EOS has retrieved and cached information about one or more files, you can retrieve information on a specific file by calling EOS_TitleStorage_CopyFileMetadataByFilename
with the name of the file, or by calling EOS_TitleStorage_CopyFileMetadataAtIndex
with the file's zero-based index within the cache. If you need to know how many files are in the cache, you can call EOS_TitleStorage_GetFileMetadataCount
. Once you no longer need your copy of this information, release the memory it was using by calling EOS_TitleStorage_FileMetadata_Release
.
After querying EOS for information about a single file, EOS_TitleStorage_GetFileMetadataCount
may reveal that the cache holds multiple files. This can happen when results from previous queries remain in the cache. In these cases, the best practice is to check that the ResultCode
within your EOS_TitleStorage_QueryFileCallbackInfo
is EOS_Success
, and to call EOS_TitleStorage_CopyFileMetadataByFilename
to access its information. Previously cached metadata is removed on successful multiple-file query.
Accessing Files
The Title Storage Interface supports reading files from the cloud asynchronously. Reading is a streaming operation, and EOS provides handles that you can use to check a stream's progress, or throttle or interrupt it.
Reading a File
To read a file from the cloud (or your local cache) with a known name, call EOS_TitleStorage_ReadFile
. You will need to pass in an EOS_TitleStorage_ReadFileOptions
initialized as follows:
Property | Value |
---|---|
ApiVersion | EOS_TITLESTORAGE_READFILEOPTIONS_API_LATEST |
LocalUserId | (Optional) The Account ID of the local user who is reading the requested file |
Filename | The name of the file to read |
ReadChunkLengthBytes | The maximum amount of data to read in a single EOS_TitleStorage_OnReadFileDataCallback call |
ReadFileDataCallback | Callback function that handles data as it comes in, and can stop the transfer early |
FileTransferProgressCallback | Optional callback function to inform you of transfer progress; will be called at least once if set |
This function returns an EOS_HTitleStorageFileTransferRequest
handle that you can use to check the progress of the transfer, get the name of the file, or cancel the transfer. At any time during the transfer, call EOS_TitleStorageFileTransferRequest_GetFileRequestState
to poll its current state, EOS_TitleStorageFileTransferRequest_GetFilename
to check the name of the file being transferred, or EOS_TitleStorageFileTransferRequest_CancelRequest
to cancel it (without generating an error). If you prefer to receive updates from EOS rather than polling the transfer directly, provide a valid EOS_TitleStorage_OnFileTransferProgressCallback
function when initiating the transfer (as the FileTransferProgressCallback
parameter), and EOS will call it (with an EOS_TitleStorage_FileTransferProgressCallbackInfo
parameter) periodically inform you of the progress of the file transfer. If you choose this route, you are guaranteed to receive at least one call to your callback function. Using the callback function does not preclude using the handle, though they serve very similar purposes and most use cases will not require both.
When a chunk of the file comes through, your ReadFileDataCallback
(of type EOS_TitleStorage_OnReadFileDataCallback
) will run with a parameter of type EOS_TitleStorage_ReadFileDataCallbackInfo
. This structure includes a chunk of the actual data from the file, as well as a variable indicating whether or not this is the last chunk. It also has an enumerated return type, EOS_TitleStorage_EReadResult
, which you can use to instruct EOS to continue the transfer, end it due to an error, or cancel it without reporting an error.
Once the file transfer has completed, EOS will run your EOS_TitleStorage_OnReadFileCompleteCallback
callback function with an EOS_TitleStorage_ReadFileCallbackInfo
parameter. This parameter indicates success or failure and includes the name of the file.
EOS may cache files locally to speed up future read operations. These files will be encrypted with the key you provided during EOS Platform initialization. Data chunks sent to your ReadFileDataCallback
function will not be encrypted.
The following timeline diagram shows a hypothetical read operation in action:
When downloading multiple files in succession, you can improve performance by querying the file list first, caching the metadata, and then performing downloads. This avoids having to perform multiple queries and wait for the results between file downloads.
Data Caching and Encryption
The Title Storage Interface caches file data and metadata in the CacheDirectory
folder on the client system. Whenever possible, EOS will use this data instead of streaming from the cloud using MD5 checksum testing to prevent data corruption and to determine when the locally cached file is identical to the version on the cloud, in which case read operation can complete in a single callback cycle. Any successful read operation updates the cache. EOS does not clear the cache upon shutdown, enabling reuse of cached files in future sessions.
Title Storage files are always stored with encryption, using the key you provide during EOS Platform initialization. The encryption key itself is not stored on the cloud, preventing both Epic Games and malicious third parties from using the key to access data. Encryption key is identical for all the users of a product.
Outdated or unused cached files are periodically removed automatically by EOS, but you can manually clear the cache (for example, if you have very limited local storage space) by calling the EOS_TitleStorage_DeleteCache
function. You will need to pass in an EOS_TitleStorage_DeleteCacheOptions
initialized as follows:
Property | Value |
---|---|
ApiVersion | EOS_TITLESTORAGE_DELETECACHEOPTIONS_API_LATEST |
LocalUserId | The Account ID of the local user |
This function should not be needed in most scenarios. Deleting the cache can increase the number of downloads that the system makes, and can negatively impact both game and back-end service performance.
File Overriding
You can manage default files in your game code, but you might want to provide alternate versions of these files. For example, each game server may have its own configuration settings file that you want to use. You must manage these alternate files through the Developer Portal. There, you can configure settings for the files, including specifying who should receive the alternate files. When you query the file through the Title Storage Interface, the Title Storage Interface then returns the alternate file, if applicable.
See the Title Storage Management documentation for more information.
File Decryption Tool
You can the File Decryption Tool to create new files or decrypt files loaded to Title Storage or Player Data Storage easily and conveniently.
Usage Limitations
Title Storage enables developers using Epic Online Services (EOS) to distribute game-specific encrypted data from cloud servers. Data can be grouped via tags and is available to all users across all platforms. For general information about throttling, usage quotas, and best practices, see Service Usage Limitations.
Presently, there are no individual file size limits for Title Storage, but see below for other limitations:
Feature | Service Limit |
---|---|
Folder size limit | 10 GB |
Max number of files | 100 |
Differences from Player Data Storage
The Title Storage Interface and the Player Data Storage Interface both deal with cloud-based data files, but in different ways and for different purposes. The following are the major differences between the two:
-
The Title Storage Interface only queries and downloads files that have been put into the cloud through the Developer Portal, while the Player Data Storage Interface can also create, modify, and delete files.
-
The Title Storage Interface deals with files on a per-product basis; these files are common to all users of the product. The Player Data Storage Interface works on a per-user basis, and files are private to each user.
-
The two interfaces implement file encryption differently. See the Data Caching and Encryption section for more details.
-
The Title Storage Interface supports conditional file overriding, enabling developers to provide different versions of files based on various conditions. See the File Overriding section for more details.
-
File queries with the Title Storage Interface can make use of a tagging system to group related files together.
-
Because the Title Storage Interface does not upload files, user throttling is not a concern.