Content - Overview¶
The Content feature allows game maker to store project-specific data objects. It's embedded into many Beamable features, such as Inventory, Store, Leaderboards, and Tournaments. For simplicity, some Beamable data structures may be omitted from this diagram.
Content ID¶
The content ID is assigned at creation of a new content, and is composed of content type and content id. A content ID always starts with the content type. For example, a currency content for dollars would be:
currency.dollars.
One important concept of the Content ID is the "Nesting". Content IDs can be nested, and the resulting hierarchy will be baked in to the name. For example, to group "weekend" events under a common folder -- the content ID would be:
events.weekend.<user-defined-id>.
Content Namespaces¶
Content is validated as a manifest which allows items to be validated against each other. This prevents validation errors when publishing; however, individual changes could cause validation errors after uploading; e.g., a store references a currency that no longer exists.
Namespaces are locations for content to be published so that the content does not impact content in other namespaces. Content namespaces can also be used for versioning in order to ensure older versions of the game using the same or similar content do not break.
Warning
Beamable APIs that use content under the hood can only look to the global namespace.
Content Data¶
Content types are must extend Beamable.Common.Content.ContentObject. All derive from Unity's ScriptableObject. The Beamable SDK for Unity ships with all content types needed for common use cases.
| Class Name | Related Feature | Coding Required? |
|---|---|---|
AnnouncementContent |
Announcements | No |
CalendarContent |
-- | No |
CurrencyContent |
Currency | No |
EmailContent |
No | |
EventContent |
Events | No |
GroupDonationsContent |
Groups | No |
ItemContent |
Inventory | Optional; game makers may add InventoryBehaviour for custom item behavior. |
LeaderboardContent |
Leaderboard | Optional; game makers may add custom code for client-authoritative scoring. |
ListingContent |
Store | Optional; game makers may add custom code for custom listing rendering. |
SimGameType |
Multiplayer | Optional; game makers may add custom game types. |
SKUContent |
Store | No |
StoreContent |
Store | No |
TournamentContent |
Tournaments | No |
VipContent |
-- | No |
Beamable Serialization of Custom Content Types¶
Unity's built-in types use Unity's serialization. However, Beamable's custom content types rely instead on Beamable's custom serialization. This serialization is strict and has limitations.
| Supported Types | Unsupported Types |
|---|---|
• Unity's AssetReference• Unity's Color• bool• double• enum• float• int• List• long• string• System.Object (and child types)• ContentRef• ContentLink |
• Unity's MonoBehaviour• Unity's ScriptableObject• Etc... |
The [IgnoreContentFieldAttribute] can be applied to any field that you wish to exclude from the Content Serialization process.
MyCustomContent.cs
1 2 3 4 5 6 7 8 9 10 11 | |
Inheritance Hierarchies¶
There might be cases where you want to have some hierarchy chain of ContentObject but have one of the types in the chain not be an actual ContentType; for example, to share code between different child ContentTypes but in a parent class that can never be created directly as a piece of Beamable content. You can do that by making the class abstract and not marking it as a ContentType.
The snippet below demonstrate what that would look like.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Content API¶
Subscribing to Content Changes¶
The ContentService API allows you to subscribe to content changes on the server. This is useful for dynamically updating content in your game without requiring a full game update.
You can subscribe to all content changes, or filter by a specific type of content. The example below demonstrates both methods.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
Beamable supports subscriptions to Content as well as direct references to certain pieces of content. Both of these will allow you to download content from the server, depending on the Game Maker's needs.
ContentLink and ContentRef¶
Subscriptions use a PlatformSubscription to dynamically read the data on the server, and fire a callback when the data is changed. However, ContentLink and ContentRef are both resolved manually when the data is needed.
Beamable supports 2 methodologies for referencing a content object; ContentLink and ContentRef. While they are both very similar syntactically and need to be resolved before using, they perform differently and have different use-cases.
ContentLink- Beamable will perform a first frame load to resolve the reference.ContentLinks must be present and resolvable (that is, they cannot benull)ContentRef- Beamable will perform a lazy load to resolve the reference. As such, it is okay for aContentRefto benullas long as it is never resolved
ContentServiceExistingExample.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | |
Best Practices
- If the content that your game is using is known ahead of time (e.g. there will only be subtle differences in existing pieces of content), a content reference (such as ContentLink or ContentRef) should be used.
- However, if the content in your game needs to be more dynamic (e.g. the Game Maker will be pushing entirely new pieces of content, unknown to the game client), a content subscription should be used.
- DO: Use
ContentLinkin any member variable in your custom content type which references another content type. ContentLink is useful for data that needs to be loaded quickly at runtime, since it is preloaded in very early stages of the application's lifecycle. - DON'T: Use
ContentRefby default everywhere in your project. This is supported but is considered overkill. ContentRef is useful for data that the application can afford to load on-demand (especially data that might not get loaded at all).
GetManifest Method¶
In the SDK, the GetManifest function accepts a filter string, as shown in the example below. You can read more about filters in the Content Management section.
1 2 3 4 5 6 7 8 9 10 11 12 | |
GetContent Method¶
Beamable's ContentService has another method that can pull content: GetContent. Since this method will attempt to pull several pieces of content at once, it is often inefficient, however it may be useful depending on the scope of your project.
1 2 3 4 5 6 7 8 | |
Filter strings do not grant type safety in the SDK, and are more prone to bugs and unintentional filtering. The above sample can be re-written with the ContentQuery class instead of the filter string. The ContentQuery allows the developer to specify constraints in a type safe way and will avoid filter serialization bugs.
1 2 3 4 5 6 7 8 9 10 | |
Content with Microservices¶
This 'MyCustomContent.cs' snippet includes the [Agnostic] attribute. To make content classes available to your microservices, add the attribute to your content classes.
See Microservices for more info.
MyCustomContent.cs
1 2 3 | |
Changing Content Namespaces¶
This sample shows how to switch the default content namespace to "tuna" before resolving a CurrencyRef.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Content Management¶
Content management is critical to keep the content in your game engaging and reactive, and Beamable provides a number of content management tools. This is a mixture of solutions within the "Beamable SDK for Unity" and Rest API calls. In addition Beamable provides some extended tools that integrate with Google Sheets as a plugin.
Beamable provides a streamlined Content Publishing pipeline. You can deploy your content across multiple environments that can be tailored to your own internal publishing workflow.
When you create your Beamable account, we automatically create a "Development to Production" pipeline of distinct environments for you. These environments are "Dev" → "Staging" → "Production". This is how we enable you to publish your content to our servers for the development environment while allowing you the peace of mind to know that the "Production" environment has not been modified.
Then, once you have tested that the new content in your environment looks correct, you can go into the Portal to promote the "Dev" content to "Staging" and eventually "Production".
Storage Location of Content Types and Content Live Refresh¶
One of the main benefits of our content system is that, when you hit publish and the content updates, we will automatically refresh that content on each of the game clients via a server-to-client message. This allows for the system to be incredibly interactive at development time as well as allowing for over the air updates to players who are playing in "Production" after a content promotion.
While using the Content Manager Editor (Unity Editor) it will be saved locally to your project in the following location:
1 | |
On Client's Builds (On-device) The development location is not included in the built game project. Instead, when the player loads the game, a fresh copy of all content is retrieved from the Beamable back-end and stored on-device. This allows Beamable to serve dynamic content to the game project. By default, this is a lazy loading operation. Each of Beamable's feature prefabs show a loading progress indicator UI automatically.
Content is stored on-device in a within Unity's Application.persistentDataPath.
1 | |
Content Caching¶
Content is cached by the client and stored both in memory and persisted to disk. When content is updated on our backend, Beamable updates a client manifest and push it to all clients to invalidate and update the cache.
See source code of Runtime/DisruptorEngine/Content/ContentCache.cs for more info.
Game Content Designer¶
Config data, or "Content" as it is called within Beamable, is realm-scoped and can be deployed from either...
- Unity - Via Unity's
ScriptableObject - Google Sheets - Via Beamable's Game Content Designer
Within the context of a CI/CD pipeline, game makers can create jobs that invoke the Content deployment function against data it pulled from source control, and pass in arguments for which realm this Content should go to. This is not theoretical, this is what game makers do today in production.
Remote Configuration Workflows¶
A fundamental pattern for using Beamable Content is Remote Configuration. With modest planning, game makers can maximize the user experience while minimizing the number of game updates shipped. This workflow allows game makers to update game content remotely and do so in real-time. Games can tweak existing features, launch new features, test out functionality -- all without necessarily shipping app updates or code changes.This can be especially useful for live-ops, seasonal events, and limited-time offers.
This table summarizes the types of game changes that can be made remotely versus those that require a game update. So you can plan accordingly.
| Remote Via Portal | Requires Game Update | |
|---|---|---|
| Add/Remove/Edit Content Type | ❌ | ✔️ |
| Add/Remove/Edit C# Code | ❌ | ✔️ |
| Edit Content Type Values | ✔️ | ❌ |

