Title Storage Interface

Interface to manage encrypted data on cloud servers

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 appropriate 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 to file-management functions from the Title Storage Interface will result in failure and will return the EOS_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 return EOS_CacheDirectoryMissing or EOS_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.

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

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

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.

File metadata uses the (structure name here, linked to API) data structure, which contains the following data:

(Excerpt table from API here)

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

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:

ReadOperationDiagram.png

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

In some cases, you may want to provide different versions of a file based various on conditions; for example, different game servers may have their own configuration settings. You can redirect requests for specific file names to alternate files at the Title Storage level. To do this, set up your file structure using the Developer Portal. The back-end service will determine which file to return based on the incoming query. The end result of this setup is that the developers can request a single file name with the EOS SDK from within the application, but be provided with different file data according to the back-end system's criteria. See [Title Storage Dev Portal Experience] for more information on override set up.

Usage Limitations

Title Storage space is limited on a per-product basis, though the exact values are not fixed at this time.

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:

  1. 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.

  2. 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.

  3. The two interfaces implement file encryption differently. See the Data Caching and Encryption section for more details.

  4. 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.

  5. File queries with the Title Storage Interface can make use of a tagging system to group related files together.

  6. Because the Title Storage Interface does not upload files, user throttling is not a concern.

Encryption/Decryption Command Line Tool

The File Decryption Tool is a developer-oriented command line tool that enables you to create new files or decrypt files loaded to Title Storage easily and conveniently. To decrypt a file, you will need the encryption key and a copy of the encrypted file from Title Storage. Encrypting files requires the same key and the unencrypted file you want to encrypt.

Since the Title Storage Interface maintains a local cache, you can copy encrypted files from that cache and decrypt them.

Locate FileDecryptionTool in the SDK distribution and run it from the command line. This tool supports a single-file mode and a directory mode. Single-file mode takes a single input file, encrypts or decrypts it, and outputs the result to another file. Directory mode goes through all files in the target directory and its subdirectories, and places the output files in a duplicate directory structure elsewhere.

Because the tool supports Player Data Storage files as its default type, you will need to use the "-titlestorage" parameter to enable Title Storage mode. If the tool encounters a Player Data Storage file while in Title Storage mode, or a Title Storage file while in Player Data Storage mode, it will skip over the and report an error.

Parameter Listing

Parameter

Effect

input

Sets the path to the file (or folder) containing encrypted data to read

output

Sets the path to the file (or folder) where the decrypted data will be written

key

Sets the encryption key to use for encrypting and decrypting operations; must be in hexadecimal and no more than 64 characters long

titlestorage

Enables Title Storage mode; if this is not present, the tool will run in Player Data Storage mode

encrypt

Enables encryption mode, meaning the output files will be encrypted copies of the input files; if not set, the output files will be decrypted copies of the input files

The data format of the input files is unknown to the tool, so providing an incorrect encryption key will not cause an error. However, the output files will be unusable by the application due to the mismatch between keys.

Sample Command Lines

FileDecryptionTool -input encrypted_ts_data -output unencrypted_ts_data -key 123abcdef -titlestorage

FileDecryptionTool -input raw_ts_data_file -output encrypted_ts_data_file -key 123abcdef -encrypt -titlestorage