Content
Beamable's Content feature is a read-only (at runtime) arbitrary data store that you can use to define your game's data. Several of Beamable's own managed features also use content in some way or another.
UBeamContentObject
and Sub-types
In Unreal, you define content schemas as sub-classes of UBeamContentObject or any of its sub-types available in the SDK ( UBeamItemContent , UBeamGameType , etc...). Every content type must define a unique string id for that particular type and a function that returns it.
The following example of UBeamCurrencyContent shows how that can be done:
UCLASS(BlueprintType)
class BEAMABLECORE_API UBeamCurrencyContent : public UBeamContentObject
{
GENERATED_BODY()
public:
// Define the ContentTypeId for this type.
UFUNCTION()
void GetContentType_UBeamCurrencyContent(FString& Result){ Result = TEXT("currency"); }
// Define the properties you wish
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FBeamClientPermission clientPermission;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int64 startingAmount;
UPROPERTY(EditAnywhere, BlueprintReadWrite, DisplayName="Federation")
FOptionalBeamFederation external;
};
Please remember to annotate your UPROPERTY
with EditAnywhere
and either:
BlueprintReadOnly
if you are not writing utilities to create the objects for you.BlueprintReadWrite
if you are writing utilities to create the objects for you.
Microservices
In a lot of cases, you will want to access these content objects in Microservices. For all of Beamable's own content-types ( UBeamCurrencyContent , etc...) you will find equivalents in the Microservice SDK. For your own custom types, you'll need to declare them in C#. To do so, use the serialization table below as reference to know how to map types from C++ to C#.
Supported Content Serialization
Serializable Type | In C# Microservices | Notes |
---|---|---|
Primitive Types | ||
uint8 , int32 , and int64 |
byte , int and long . |
|
float and double . |
||
bool |
||
Unreal Types | ||
FString , FText , FName |
string |
These get serialized as JSON strings. |
FGameplayTag |
string |
FGameplayTag::RequestGameplayTag for deserialization. |
FGameplayTagContainer |
string |
FGameplayTagContainer::FromExportString for deserialization. |
UClass* |
string |
Gets converted to FSoftObjectPath when serializing. Deserializing will first create the FSoftObjectPath and then resolve it. |
TSoftObjectPtr |
string |
Gets converted to FSoftObjectPath when serializing. When None serializes as an empty string . |
TArray<> |
List<> or T[] |
Any TArray<SomeType> will serialize normally as long as SomeType is also supported. |
TMap<FString, > |
Dictionary<string,> |
We only support maps with FString as keys. The values can be any supported type. |
Beamable Types | ||
FBeamOptional |
Optional____ |
Any property of a type implementing FBeamOptional doesn't get serialized if IsSet==false but does get serialized otherwise.For example, FOptionalInt32 serializes to nothing OR an int32 . |
FBeamSemanticType |
string OR semantic type equivalent in C# |
This always gets serialized as a JSON blob when inside UBeamContentObject . |
FBeamArray and FBeamMap |
ArrayOf and MapOf |
Any implementation of these wrappers are serialized correctly as JSON arrays and JSON objects respectively. These are only used when you want to nest TArray<TArray<>> / TMap<,TMap<>> and still have Blueprint Support. |
FBeamJsonSerializableUStruct |
Any C# class that maps to your struct | Any type inheriting from this type gets serialized as a JSON object. |
IBeamJsonSerializableUObject |
Any C# class that maps to your class | UObject in content should have their classesannotated with DefaultToInstanced ,EditInlineNew since you shouldn't referenceassets directly inside content objects. For that, use TSoftObjectPtr<> . |
Take a look at UMockBeamContentObject
to see the supported types.
Beamable's Content System
Beamable Content System allows you to define arbitrary JSON-serialized data for use at runtime. The system is manifest-based and has no server-side schema enforcing (which means you are solely responsible for maintaining backward compatibility for your custom content objects).
Each individual content object in each manifest is identified by an ID with the format below:
ContentTypeId.ContentName
ContentType expands to the hierarchy of UBeamContentObject types, starting from the root type. For example:
UMyGameItemContent
inherits fromUBeamItemContent
items.mygameitem.MyGameItemName
The last part of the id is the only one you should edit through the Content Window.
At Runtime
The SDK fetches the content manifest before the OnBeamableStarted
callback is
triggered. By default, it downloads the content manifest and each individual piece of content. You can enable and disable this behaviour it can be configured to do so inside Project Settings -> Beamable Runtime
.
The SDK also supports automated content updates: once a user is signed into Beamable, our UBeamContentSubsystem
begins to listen for notifications that the realm's content manifest has been updated from Beamable's server. If that happens, we will re-download the manifest. Again, we only download individual content pieces if that setting is on. There is an API you can use to manually download individual content pieces: FetchIndividualContentBatchOperation
and FetchIndividualContentOperation
.
The Content Manifest
At any given time, a Beamable realm has one or more active Content Manifests. By default, and for most cases, the automatically created global manifest is the only one you need. To create, update and delete modify and access UBeamContentObject
instances at authoring time, you need to:
- Synchronize your local state with what's in the realm (download the manifest).
- Create content JSON files inside the
.beamable/content
folder.- The Content Window is the easiest way of doing so.
- Synchronize your changes to the Realm (publish the manifest).
In Unreal, you interact with your content objects through the Content Window. It shows you the current state of content relative to your current realm and allows you:
- Download: Download the content files currently published to your realm. This is non-destructive; it won't discard new files, just restore deleted ones and discard changes of existing ones.
- Reset: This is a destructive version of download. After it ends, your local content will 100% reflect what's in the realm.
- Publish: This is the reverse-reset. It'll make your realm an 100% match to your local content.
This UX looks and follows what you expect of editing any UObject
. The difference is that the UBeamContentObject
instances are NOT stored inside your Unreal project. They are the .json
files inside .beamable/content
folder.
Baking Content
In preparation for our Offline Mode support, we provide a editor utility that will bake a content manifest into a UBeamContentCache
; this is a special asset type that has the UBeamContentObject
instances serialized using UE's serialization as opposed to JSON.
This is loaded automatically by the UBeamContentSubsystem
if it exists and is configured correctly. We provide an editor utility blueprint you can run to generate and configure the cache for each of your content manifests. The EBP_BakeContent
utility can be found in Beamable Core's plugin folder under /Editor/Utility/EBP_BakeContent.EBP_BakeContent
.
I can't find the Beamable Core Content in the Content Browser
UE's Content Browser does not show Plugin content folders by default. If you want to see these, you need to turn it on at Content Browser -> Settings -> Show Plugin Content
.
Running this utility goes through each of your manifests (.beamable/content/{manifest}
) and turns them into BCC_
assets ( UBeamContentCache
) stored in /Game/Beamable/Content/Manifests/Cooked/
directory.