Heroic Labs Announces Unreal Nakama SDK 3.0

Nathan profile photo
Nathan
October 26, 2026

Version 3.0 of the Nakama Unreal SDK is out today. It’s a big update with three aims: make the API consistent, move to a modern async pattern, and make Nakama easier to use from C++.

A more consistent API

v3 brings the Unreal SDK in line with the rest of our client libraries, and makes it consistent with itself:

  • Aligned naming: Function names now match across our SDKs, so what you learn in Unreal carries over to our other clients and docs.
  • Two headers: Types that were spread across lots of small header files now live in NakamaTypes.gen.h and NakamaRtTypes.gen.h.
  • Consistent responses: Every call reports success or failure the same way.

Modern, future-based async

In v2, every call took two delegates, one for success and one for failure. Even a simple device login meant declaring both delegates, binding both handlers, and writing two separate callback functions:

FOnAuthUpdate AuthenticationSuccessDelegate;
AuthenticationSuccessDelegate.AddDynamic(this, &ASagiShiActor::OnAuthenticationSuccess);

FOnError AuthenticationErrorDelegate;
AuthenticationErrorDelegate.AddDynamic(this, &ASagiShiActor::OnAuthenticationError);

Client->AuthenticateDevice(DeviceId, Username, bCreate, Vars, AuthenticationSuccessDelegate, AuthenticationErrorDelegate);

void ASagiShiActor::OnAuthenticationSuccess(UNakamaSession* LoginData)
{
    UE_LOG(LogTemp, Log, TEXT("Login successful: %s"), *LoginData->SessionData.Username);
}

void ASagiShiActor::OnAuthenticationError(const FNakamaError& Error)
{
    UE_LOG(LogTemp, Error, TEXT("Failed to login: %s"), *Error.Message);
}

In v3, calls return a future, and you chain a single .Next() callback that receives a result object. Check bIsError, then use the value or the error:

Nakama::AuthenticateDevice(ClientConfig, bCreate, Username, DeviceId).Next(
    [WeakThis](const FNakamaSessionResult& AuthenticateResult)
    {
       if (AuthenticateResult.bIsError)
       {
          UE_LOG(LogTemp, Error, TEXT("Failed to log in: %s"), *AuthenticateResult.Error.Message);
          return;
       }

       if (!WeakThis.IsValid())
       {
          return;
       }

       WeakThis->Session = AuthenticateResult.Value;
       UE_LOG(LogTemp, Log, TEXT("Log in successful: %s"), *AuthenticateResult.Value.Username);
    });

Success and error handling now sit right next to the call, so the code reads top to bottom instead of being spread across bound delegates and member functions.

One thing to watch: the callback runs after the calling function has returned, so don’t capture locals by reference. Keep your config and session as members of a long-lived object, like your actor, and capture a weak pointer to it, as in the example above.

A more convenient API

  • Plain structs instead of client objects: UNakamaClient and UNakamaSession used to be UObjects. They’re now the USTRUCTs FNakamaClientConfig and FNakamaSession, so there’s no client object to create or keep alive. Build a config once and pass it to the calls you make.
  • Namespaced calls: Regular API calls live under Nakama:: and realtime calls under NakamaRt::, with FNakamaRtConnection handling the realtime socket.
  • Simpler realtime connection: You no longer need a pair of delegates and handler functions to connect:
RtConnection = MakeShared<FNakamaRtConnection>();

const FNakamaWebSocketConnectionParams ConnectionParams = { Host, Session.Token, PingIntervalSeconds, Port, bUseSSL };

RtConnection->Connect(ConnectionParams).Next([](const FNakamaWebSocketConnectionResult& ConnectionResult)
{
    if (ConnectionResult.ErrorCode != ENakamaWebSocketError::None)
    {
       UE_LOG(LogTemp, Error, TEXT("Socket connection failed: %d"), (uint8)ConnectionResult.ErrorCode);
       return;
    }

    UE_LOG(LogTemp, Log, TEXT("Socket connection succeeded"));
});

Upgrading from v2

Upgrading takes a handful of structural changes: replace the plugin, update Build.cs, switch to the new call pattern, and update your includes and realtime type names. If your project uses the old async Blueprint nodes, we’ve included a script that removes them safely before you upgrade, because Unreal doesn’t cope well with broken async nodes.

To help developers who are planning on migrating their existing projects from v2 to v3, we put together a handy migration guide to help you along the way.

Get started

Enterprise game backends

See how studios ship multiplayer at scale without rebuilding infrastructure.

Walk through Nakama and Heroic Cloud: org-level access control and managed ops without rewriting your stack. Book a demo to see it in action.

  • SOC 2 Type II certified
  • Proven at 2M concurrent users
  • Dedicated capacity, no CCU limits