Appearance
Blob Storage Outside AWS
How the game server reaches its blob storage in an environment hosted outside AWS, and what changes for your game.
Appearance
How the game server reaches its blob storage in an environment hosted outside AWS, and what changes for your game.
Your game server keeps files in blob storage: published game configs, uploaded player incident reports, and the status file that tells game clients about maintenance, among others. In an environment hosted on AWS, that storage is S3, and the game server reaches it with the process's AWS configuration.
In an environment hosted outside AWS, Metaplay supports S3-compatible storage instead, and configures the game server's access to it through the BlobStorage runtime options. Your game code uses it the same way it uses S3, with the few differences this page describes.
Requires Release 39
Release 39 is the first SDK release that can use S3-compatible storage. A game server on an older release does not support running outside AWS.
The game server stores its blobs in two buckets with different access:
In an environment that Metaplay provides, the BlobStorage runtime options already point at both buckets. To use S3-compatible storage of your own instead, set Backend to S3Compatible and point the options at your service:
BlobStorage:
Backend: S3Compatible
S3ServiceUrl: http://storage.example.internal:7070
S3ServicePublicUrl: https://s3.example.com
S3ServiceAccessKey: example-key-id
S3ServiceSecretKey: example-secret
S3Region: example-region
S3PublicBucketName: my-game-public
S3PrivateBucketName: my-game-private
S3PublicBucketCdnUrl: https://cdn.example.com/S3ServiceUrl - The URL of the S3-compatible service the server uses for its storage.S3ServicePublicUrl - Optional URL of the service in presigned URLs, such as a public host your game clients can reach. It defaults to S3ServiceUrl.S3ServiceAccessKey and S3ServiceSecretKey - The credentials for S3ServiceUrl.S3Region - The region of the buckets.S3PublicBucketName and S3PrivateBucketName - The names of the public and private buckets.S3PublicBucketCdnUrl - The URL of the public bucket for game clients, such as a CDN in front of it.To set the options, and to see the values your server runs with on the LiveOps Dashboard, see Working with Runtime Options.
Create your storage from the BlobStorage options, as you would on AWS. CreatePublicBlobStorage and CreatePrivateBlobStorage return an IBlobStorage configured for the environment's storage, wherever the environment is hosted.
BlobStorageOptions blobOpts = RuntimeOptionsRegistry.Instance.GetCurrent<BlobStorageOptions>();
using IBlobStorage storage = blobOpts.CreatePrivateBlobStorage("MyFeature");
await storage.PutAsync("Summary.json", summaryBytes);To use an S3 operation that IBlobStorage doesn't offer, you can use the raw S3 client of the storage. Note that in an environment that Metaplay provides, the storage rejects changes to bucket-level configuration, such as bucket policies, CORS rules and lifecycle rules.
S3BlobStorage myStorage = ...;
await myStorage.Client.CustomOperationAsync(myStorage.BucketName, myStorage.GetEntryKeyName("Summary.json"));A presigned URL lets a game client read or write one file without credentials of its own. Create one with GetPresignedUrlAsync, which signs it for S3ServicePublicUrl if it is set, and for S3ServiceUrl otherwise.
S3BlobStorage myStorage = ...;
string uploadUrl = await myStorage.GetPresignedUrlAsync(HttpVerb.PUT, "Uploads/Report.bin", TimeSpan.FromMinutes(15));S3-compatible storage commonly doesn't support object access control lists (ACLs). In an environment that Metaplay provides, the storage ignores a canned ACL on a write, and rejects a write that grants an ACL. Whether an object is publicly readable depends only on its bucket.
The storage can have a limit on how much it stores. When a write would take the storage over its limit, PutAsync() throws BlobStorageQuotaExceededException.
try
{
await storage.PutAsync(fileName, bytes);
}
catch (BlobStorageQuotaExceededException)
{
// The storage is full.
// Note: BlobStorageQuotaExceededException derives from IOException, so
// we need to catch it before plain IOException.
}
catch (IOException)
{
// Any other failed write.
}When using the raw S3 client, an AmazonS3Exception with the error code QuotaExceeded is thrown instead. Reads still work while the storage is full.
A game server whose storage is full cannot publish a new game config or localizations. If you include a new game config or localization in your server build, the server fails to start until there is space to publish those blobs.
Some SDK features use AWS directly, and the BlobStorage configuration has no effect on them, or only a partial effect, as listed below. They need AWS credentials, which an environment outside AWS doesn't provide, so these features work there only when you provide them:
JSON-to-S3 analytics sink - By default, the sink writes to the private bucket of the BlobStorage configuration, so it works wherever the server's storage does.
If AnalyticsSinkJsonBlobStorage:S3BucketName and AnalyticsSinkJsonBlobStorage:S3Region are set, the sink writes to that AWS S3 bucket instead, with the server's AWS credentials.
Database snapshot import - The server reads an exported database snapshot from the AWS S3 bucket in DatabaseIngest:S3Bucket and DatabaseIngest:S3Region, with the server's AWS credentials.
Web3 NFT metadata storage - The server writes NFT metadata to the AWS S3 bucket in Web3:NftBucketName and Web3:S3Region, or the bucket an NFT collection overrides them with, with the server's AWS credentials.
If Web3:UsePseudoBucketInPublicBlobStorage is set, the server writes the metadata to the public bucket of the BlobStorage configuration instead.