Unreal SDK 2.0.0 Migration Guide
This guide summarizes the differences between versions 1.x.x and 2.0.0 and shows how to migrate to Unreal SDK 2.0.0.
Unreal SDK version 2.0.0 introduces UPubnubClient as the primary API entry point, enabling multiple independent PubNub contexts. This release also adds synchronous method variants, an advanced logging system, structured result types, and dedicated input structs for App Context operations.
No Unreal SDK 1.x.x support
If your application uses Unreal SDK 1.x.x, it continues to work. We recommend migrating to Unreal 2.0.0 to access new features and improvements. Version 1.x.x receives only critical security fixes.
What has changed
See the major differences between versions:
| Feature/Method | Unreal SDK 1.x.x | Unreal SDK 2.0.0 |
|---|---|---|
| Entry point | UPubnubSubsystem (single context) | UPubnubClient (multiple contexts) |
| Method pattern | Async-only (callback required) | Sync + Async variants (Method() and MethodAsync()) |
| Operation results | Returned via callback params | FPubnubOperationResult in result structs and callbacks |
| Delegate names | FOn...Response (e.g., FOnPublishMessageResponse) | FOnPubnub...Response (e.g., FOnPubnubPublishMessageResponse) |
| Pagination | Separate PageNext/PagePrev strings | FPubnubPage struct with Next and Prev |
| App Context inputs | FPubnubUserData for set operations | FPubnubUserInputData with ForceSet* fields |
| Paginated total count | Not available | TotalCount field in result structs and IncludeTotalCount in include structs |
| Logging | UE_LOG only | Configurable IPubnubLoggerInterface with levels and sources |
| Entities | Reference UPubnubSubsystem | Reference UPubnubClient |
Breaking changes
UPubnubClient replaces UPubnubSubsystem as the primary entry point
Unreal SDK 2.0.0 introduces UPubnubClient as the main class for all PubNub operations. UPubnubSubsystem now serves as a factory that creates and manages UPubnubClient instances. This lets you run multiple independent PubNub contexts simultaneously, each with its own keys, user ID, and subscriptions.
- Before (v1.x.x)
- After (v2.x.x)
// Get the subsystem and call methods directly
UPubnubSubsystem* PubnubSubsystem = GetGameInstance()
->GetSubsystem<UPubnubSubsystem>();
PubnubSubsystem->InitPubnub();
PubnubSubsystem->SetUserID("my-user");
PubnubSubsystem->PublishMessage(
"my-channel",
"Hello!",
FOnPublishMessageResponse()
);
// Get the subsystem, create a client, then call methods on the client
UPubnubSubsystem* PubnubSubsystem = GetGameInstance()
->GetSubsystem<UPubnubSubsystem>();
FPubnubConfig PubnubConfig = FPubnubConfig({.PublishKey = "demo", .SubscribeKey = "demo", .UserID = "Player_001"});
UPubnubClient* PubnubClient = PubnubSubsystem->CreatePubnubClient(PubnubConfig);
PubnubClient->PublishMessageAsync(
"my-channel",
"Hello!",
FOnPubnubPublishMessageResponse()
);
FPubnubConfig now includes a LoggerConfig field of type FPubnubLoggerConfig for configuring the advanced logger.
Synchronous and asynchronous method variants
In v1.x.x, all methods were asynchronous and required a callback delegate. In v2.0.0, every method has both a synchronous (blocking) and asynchronous variant:
- Synchronous
MethodName(), which blocks until complete and returns a result struct - Asynchronous
MethodNameAsync(), which is non-blocking with a callback delegate
- Before (v1.x.x)
- After (v2.x.x)
// Async-only, callback was required for Blueprint-exposed version
FOnPublishMessageResponseNative PublishMessageResponse;
PublishMessageResponse.BindLambda([](FPubnubMessageData Msg)
{
// Handle result
});
PubnubSubsystem->PublishMessage(
"my-channel",
"Hello!",
PublishMessageResponse);
// Synchronous - blocks and returns result
FPubnubPublishMessageResult SyncResult = PubnubClient->PublishMessage(
"my-channel",
"Hello!"
);
if (!SyncResult.Result.Error)
{
// Success - use SyncResult.PublishedMessage
}
// Asynchronous - use native callback with BindLambda (do not use CreateLambda directly in the call)
FOnPubnubPublishMessageResponseNative PublishMessageResponse;
PublishMessageResponse.BindLambda([](FPubnubOperationResult Result, FPubnubMessageData Msg)
{
show all 21 linesThis pattern applies to all methods.
New result structs with FPubnubOperationResult
Unreal SDK 2.0.0 introduces FPubnubOperationResult as a standardized error-reporting struct that is included in all result types.
USTRUCT(BlueprintType)
struct FPubnubOperationResult
{
// HTTP status code. 200 if the operation succeeded.
int Status = 0;
// Whether the operation encountered an error.
bool Error = false;
// Description of the error, if any.
FString ErrorMessage = "";
};
Each operation now has a dedicated result struct that wraps FPubnubOperationResult with operation-specific data:
| Result struct | Fields (besides Result) |
|---|---|
FPubnubPublishMessageResult | PublishedMessage |
FPubnubSignalResult | SignalMessage |
FPubnubListChannelsFromGroupResult | Channels |
FPubnubListUsersFromChannelResult | Data |
FPubnubListUsersSubscribedChannelsResult | Channels |
FPubnubGetStateResult | StateResponse |
FPubnubGrantTokenResult | Token |
FPubnubFetchHistoryResult | Messages |
FPubnubMessageCountsResult | MessageCounts |
FPubnubMessageCountsMultipleResult | MessageCountsPerChannel |
FPubnubGetAllUserMetadataResult | UsersData, Page, TotalCount |
FPubnubGetAllChannelMetadataResult | ChannelsData, Page, TotalCount |
FPubnubUserMetadataResult | UserData |
FPubnubChannelMetadataResult | ChannelData |
FPubnubMembershipsResult | MembershipsData, Page, TotalCount |
FPubnubChannelMembersResult | MembersData, Page, TotalCount |
FPubnubGetMessageActionsResult | MessageActions |
FPubnubAddMessageActionResult | MessageActionData |
These structs are returned by synchronous methods and are also used as the first parameter in async callback delegates.
Delegate renames
Callback delegates on UPubnubClient are prefixed with FOnPubnub to avoid naming collisions and improve clarity. The UPubnubSubsystem retains the old delegate names for backward compatibility.
| v1.x.x delegate | v2.0.0 client delegate |
|---|---|
FOnPublishMessageResponse | FOnPubnubPublishMessageResponse |
FOnSignalResponse | FOnPubnubSignalResponse |
FOnSubscribeOperationResponse | FOnPubnubSubscribeOperationResponse |
FOnAddChannelToGroupResponse | FOnPubnubAddChannelToGroupResponse |
FOnRemoveChannelFromGroupResponse | FOnPubnubRemoveChannelFromGroupResponse |
FOnListChannelsFromGroupResponse | FOnPubnubListChannelsFromGroupResponse |
FOnRemoveChannelGroupResponse | FOnPubnubRemoveChannelGroupResponse |
FOnListUsersSubscribedChannelsResponse | FOnPubnubListUsersSubscribedChannelsResponse |
FOnListUsersFromChannelResponse | FOnPubnubListUsersFromChannelResponse |
FOnSetStateResponse | FOnPubnubSetStateResponse |
FOnGetStateResponse | FOnPubnubGetStateResponse |
FOnGrantTokenResponse | FOnPubnubGrantTokenResponse |
FOnRevokeTokenResponse | FOnPubnubRevokeTokenResponse |
FOnFetchHistoryResponse | FOnPubnubFetchHistoryResponse |
FOnMessageCountsResponse | FOnPubnubMessageCountsResponse |
FOnDeleteMessagesResponse | FOnPubnubDeleteMessagesResponse |
FOnGetAllUserMetadataResponse | FOnPubnubGetAllUserMetadataResponse |
FOnGetUserMetadataResponse | FOnPubnubGetUserMetadataResponse |
FOnSetUserMetadataResponse | FOnPubnubSetUserMetadataResponse |
FOnRemoveUserMetadataResponse | FOnPubnubRemoveUserMetadataResponse |
FOnGetAllChannelMetadataResponse | FOnPubnubGetAllChannelMetadataResponse |
FOnGetChannelMetadataResponse | FOnPubnubGetChannelMetadataResponse |
FOnSetChannelMetadataResponse | FOnPubnubSetChannelMetadataResponse |
FOnRemoveChannelMetadataResponse | FOnPubnubRemoveChannelMetadataResponse |
FOnGetMembershipsResponse | FOnPubnubGetMembershipsResponse |
FOnSetMembershipsResponse | FOnPubnubSetMembershipsResponse |
FOnRemoveMembershipsResponse | FOnPubnubRemoveMembershipsResponse |
FOnGetChannelMembersResponse | FOnPubnubGetChannelMembersResponse |
FOnSetChannelMembersResponse | FOnPubnubSetChannelMembersResponse |
FOnRemoveChannelMembersResponse | FOnPubnubRemoveChannelMembersResponse |
FOnGetMessageActionsResponse | FOnPubnubGetMessageActionsResponse |
FOnAddMessageActionResponse | FOnPubnubAddMessageActionResponse |
FOnRemoveMessageActionResponse | FOnPubnubRemoveMessageActionResponse |
Multicast delegates on the client also changed:
| v1.x.x (on subsystem) | v2.0.0 (on client) |
|---|---|
FOnMessageReceived | FOnPubnubMessageReceived |
FOnSubscriptionStatusChanged | FOnPubnubSubscriptionStatusChanged |
Pagination with FPubnubPage
Paginated operations now use a FPubnubPage struct instead of separate PageNext and PagePrev string parameters.
- Before (v1.x.x)
- After (v2.x.x)
// Separate string parameters - use BindLambda for async callback (not CreateLambda in call)
FOnGetAllUserMetadataResponseNative GetAllUserMetadataResponse;
GetAllUserMetadataResponse.BindLambda([](FPubnubOperationResult Result,
const TArray<FPubnubUserData>& Users,
FString PageNext,
FString PagePrev)
{
// Use PageNext for next page
});
PubnubSubsystem->GetAllUserMetadata(GetAllUserMetadataResponse);
// Passing page tokens as separate strings
PubnubSubsystem->GetAllUserMetadata(
MyCallback,
FPubnubGetAllInclude(),
show all 21 lines// FPubnubPage struct in result
FPubnubGetAllUserMetadataResult SyncResult =
PubnubClient->GetAllUserMetadata();
FString NextPage = SyncResult.Page.Next;
// Pass FPubnubPage for next request
FPubnubPage Page;
Page.Next = NextPage;
FPubnubGetAllUserMetadataResult NextResult =
PubnubClient->GetAllUserMetadata(
FPubnubGetAllInclude(),
100, // Limit
"", // Filter
show all 18 linesNew input structs for App Context
Set operations for App Context now use dedicated input structs instead of the full data structs. These input structs exclude server-generated fields (UserID/ChannelID, Updated, ETag) and include ForceSet* booleans to explicitly set empty fields to null on the server.
| v1.x.x input type | v2.0.0 input type |
|---|---|
FPubnubUserData | FPubnubUserInputData |
FPubnubChannelData | FPubnubChannelInputData |
FPubnubMembershipInputData | FPubnubMembershipInputData (with ForceSet* fields) |
FPubnubChannelMemberInputData | FPubnubChannelMemberInputData (with ForceSet* fields) |
- Before (v1.x.x)
- After (v2.x.x)
// Used FPubnubUserData directly (UserID field ignored)
FPubnubUserData UserData;
UserData.UserName = "John Doe";
UserData.Email = "john@example.com";
PubnubSubsystem->SetUserMetadata(
"user-123",
UserData,
FOnSetUserMetadataResponse()
);
// Use FPubnubUserInputData (no UserID/Updated/ETag)
FPubnubUserInputData UserInput;
UserInput.UserName = "John Doe";
UserInput.Email = "john@example.com";
// Synchronous
FPubnubUserMetadataResult Result =
PubnubClient->SetUserMetadata("user-123", UserInput);
// To clear a field on the server, use ForceSet
FPubnubUserInputData ClearInput;
ClearInput.ForceSetEmail = true; // Email="" sent as null
ClearInput.UserName = "John Doe";
// Or force-set all fields at once
show all 16 linesEach input struct provides a static converter from the corresponding data struct:
// Convert from server response data to input data
FPubnubUserInputData Input =
FPubnubUserInputData::FromPubnubUserData(existingUserData);
TotalCount in paginated responses
Paginated responses now include a TotalCount field. To request it, set IncludeTotalCount = true in the relevant include struct (FPubnubGetAllInclude, FPubnubMembershipInclude, or FPubnubMemberInclude).
- Before (v1.x.x)
- After (v2.x.x)
// No TotalCount available - use BindLambda for async callback (not CreateLambda in call)
FOnGetAllUserMetadataResponseNative GetAllUserMetadataResponse;
GetAllUserMetadataResponse.BindLambda([](FPubnubOperationResult Result,
const TArray<FPubnubUserData>& Users,
FString PageNext,
FString PagePrev)
{
// No way to know total count
});
PubnubSubsystem->GetAllUserMetadata(GetAllUserMetadataResponse);
// Request TotalCount
FPubnubGetAllInclude Include;
Include.IncludeTotalCount = true;
FPubnubGetAllUserMetadataResult Result =
PubnubClient->GetAllUserMetadata(Include);
int Total = Result.TotalCount;
Advanced logger system
Unreal SDK 2.0.0 replaces basic UE_LOG logging with a configurable logger system. You can control log levels, filter by source (UE SDK or C-Core), and register custom loggers.
Enable and configure the default logger through FPubnubLoggerConfig in FPubnubConfig:
1
For details on log levels, log sources, and creating custom loggers, refer to the Unreal SDK Logging documentation.
Entity and subscription changes
Entities and subscriptions now reference UPubnubClient instead of UPubnubSubsystem. Entity methods follow the same sync/async pattern introduced in 2.0.0. For async entity methods, use BindLambda on a native callback (do not use CreateLambda directly in the call).
- Before (v1.x.x)
- After (v2.x.x)
// Entities were created by the subsystem
UPubnubChannelEntity* Channel =
PubnubSubsystem->CreateChannelEntity("my-channel");
// All methods were async-only - use BindLambda for callback
FOnPublishMessageResponseNative PublishMessageResponse;
PublishMessageResponse.BindLambda([](FPubnubMessageData Msg)
{
// Handle result
});
Channel->PublishMessage("Hello!", PublishMessageResponse);
// Subscription referenced subsystem internally
UPubnubSubscription* Sub = Channel->CreateSubscription();
Sub->Subscribe();
// Entities are created by the client
UPubnubChannelEntity* Channel =
PubnubClient->CreateChannelEntity("my-channel");
// Sync variant
FPubnubPublishMessageResult Result =
Channel->PublishMessage("Hello!");
// Async variant - use BindLambda for callback (not CreateLambda in call)
FOnPubnubPublishMessageResponseNative PublishMessageResponse;
PublishMessageResponse.BindLambda([](FPubnubOperationResult Result, FPubnubMessageData Msg)
{
// Handle result
});
Channel->PublishMessageAsync("Hello!", PublishMessageResponse);
show all 27 linesMigration steps
To migrate from Unreal SDK 1.x.x to 2.0.0:
-
Update your PubNub plugin to version 2.0.0.
-
Replace direct
UPubnubSubsystemmethod calls withUPubnubClient:Action Description Create a UPubnubClientusingUPubnubSubsystem::CreatePubnubClient()All PubNub operations are now called on UPubnubClientinstead ofUPubnubSubsystem.Pass FPubnubConfigtoCreatePubnubClient()Configuration is now passed when creating a client, including the new LoggerConfigfield. -
Update method names to the new sync/async pattern:
Action Description Rename async method calls from MethodName()toMethodNameAsync()For example, PublishMessage(Channel, Message, Callback)becomesPublishMessageAsync(Channel, Message, Callback).Use sync methods where callbacks are not needed For example, FPubnubPublishMessageResult Result = Client->PublishMessage(Channel, Message). -
Update delegate type names:
Action Description Add Pubnubprefix to all delegate typesFor example, FOnPublishMessageResponsebecomesFOnPubnubPublishMessageResponse. -
Update pagination parameters:
Action Description Replace PageNext/PagePrevstring params withFPubnubPageCreate a FPubnubPagestruct and set itsNext/Prevfields.Update callbacks to use FPubnubPageinstead of separate stringsPaginated callbacks now pass FPubnubPage Pageandint TotalCountinstead ofFString PageNext, FString PagePrev. -
Update App Context set operations:
Action Description Replace FPubnubUserDatawithFPubnubUserInputDatainSetUserMetadataThe new struct excludes server-generated fields and adds ForceSet*booleans.Replace FPubnubChannelDatawithFPubnubChannelInputDatainSetChannelMetadataSame pattern as user metadata. Use FromPubnubUserData()/FromPubnubChannelData()converters if neededStatic methods on input structs convert from response data types. -
Configure logging:
Action Description Set LoggerConfiginFPubnubConfigif you need custom log levelsThe default logger is enabled by default with Warninglevel.Implement IPubnubLoggerInterfacefor custom loggingRegister custom loggers via Config.LoggerConfig.InitialLoggers. -
Update entity usage:
Action Description Create entities from UPubnubClientinstead ofUPubnubSubsystemFor example, Client->CreateChannelEntity()instead ofSubsystem->CreateChannelEntity().Update entity method calls to the sync/async pattern Entity methods follow the same naming convention as client methods. -
Test your application. Pay special attention to initialization flow, publish/subscribe operations, App Context calls, and entity-based subscriptions.
Additional resources
For API details, see the Unreal SDK documentation. For questions or issues, contact PubNub support.