PlayKit.ai

Core Concepts

Understand the PlayKit Unreal SDK architecture and key concepts

Core Concepts

This page explains the core concepts and architecture of the PlayKit Unreal SDK.

SDK Architecture

The PlayKit SDK follows Unreal Engine conventions and is designed for both Blueprint and C++ usage.

Blueprint Function Library

The main entry point is UPlayKitBlueprintLibrary, which provides static functions accessible from any Blueprint:

  • Factory Methods: Create client instances (Chat, Image, STT, Player)
  • SDK State: Check if SDK is ready, get version info
  • Settings Access: Get configured Game ID, base URL, auth tokens

Client Classes

Each AI capability has a dedicated client class:

ClientClassPurpose
ChatUPlayKitChatClientText generation and conversations
ImageUPlayKitImageClientAI image generation
STTUPlayKitSTTClientSpeech-to-text transcription
PlayerUPlayKitPlayerClientUser info and credits management
NPCUPlayKitNPCClientNPC conversation component

Subsystems

The SDK uses Unreal's Subsystem pattern for global state:

  • UPlayKitPlayerClient: UGameInstanceSubsystem — manages player info, credits, and token storage
  • UPlayKitAIContextManager: UGameInstanceSubsystem — manages global player context and NPC history compaction
  • UPlayKitDeviceAuthFlow: UObject — orchestrates the device authentication flow

Authentication

Authentication Flow

┌──────────────────�?    ┌──────────────────�?    ┌──────────────────�?�?  Developer      �?    �?  Device Auth    �?    �?  Player         �?�?  Token Mode     �?    �?  Flow           �?    �?  Token Mode     �?└────────┬─────────�?    └────────┬─────────�?    └────────┬─────────�?         �?                       �?                       �?         �?                       �?                       �?    ┌─────────────────────────────────────────────────────────────�?    �?                   PlayKitAuthSubsystem                      �?    �?                                                             �?    �? �?Token storage and retrieval                               �?    �? �?Automatic token refresh                                   �?    �? �?Authentication state management                           �?    └─────────────────────────────────────────────────────────────�?```

### Developer Token

For development and testing:

```cpp
// Configured in Project Settings
// Or set programmatically:
UPlayKitSettings* Settings = GetMutableDefault<UPlayKitSettings>();
Settings->DeveloperToken = TEXT("your-token");

Player Authentication

For production, the SDK handles player login via UPlayKitDeviceAuthFlow:

  1. Create a flow object
  2. Bind OnAuthUrlReady to show the URL or QR code to the player
  3. Call StartAuthFlow — the SDK polls until the player completes login
// Check if already authenticated
bool bIsAuth = UPlayKitBlueprintLibrary::IsAuthenticated();

if (!bIsAuth)
{
    UPlayKitDeviceAuthFlow* AuthFlow = UPlayKitDeviceAuthFlow::CreateDeviceAuthFlow(this);
    AuthFlow->OnAuthUrlReady.AddLambda([](const FString& Url)
    {
        // Show URL or QR code to the player
        UE_LOG(LogTemp, Log, TEXT("Login at: %s"), *Url);
    });
    AuthFlow->OnAuthSuccess.AddLambda([](const FDeviceAuthResult& Result)
    {
        UE_LOG(LogTemp, Log, TEXT("Logged in: %s"), *Result.UserId);
    });
    AuthFlow->StartAuthFlow(UPlayKitBlueprintLibrary::GetGameId());
}

Request/Response Pattern

All AI operations are event-based — call a method, the result arrives via a bound delegate.

Blueprint Pattern

[Client Node] �?[Async Operation]
                      �?              ┌──────────────�?              �? On Success  │──�?Handle response
              └──────────────�?                      �?              ┌──────────────�?              �? On Failure  │──�?Handle error
              └──────────────�?```

### C++ Pattern

```cpp
// Bind events before calling any method
ChatClient->OnChatResponse.AddDynamic(this, &AMyActor::HandleResponse);
ChatClient->OnError.AddDynamic(this, &AMyActor::HandleError);

// Fire the request — result arrives in HandleResponse
ChatClient->GenerateText(TEXT("Hello, who are you?"));

Message History

UPlayKitChatClient is stateless — it does not track conversation history. For multi-turn context, build a TArray<FPlayKitChatMessage> and pass it via GenerateTextAdvanced(Config).

UPlayKitNPCClient manages history automatically:

// NPC automatically tracks the full conversation
NPCClient->Talk(TEXT("Hello"));
NPCClient->Talk(TEXT("What did I just say?")); // NPC remembers

// Access or clear history
TArray<FNPCMessage> History = NPCClient->GetHistory();
NPCClient->ClearHistory();

Settings Management

UPlayKitSettings

Project settings are stored in UPlayKitSettings:

// Access settings
const UPlayKitSettings* Settings = GetDefault<UPlayKitSettings>();
FString GameId = Settings->GameId;
FString BaseUrl = Settings->BaseUrl;

// Modify settings (editor only)
UPlayKitSettings* MutableSettings = GetMutableDefault<UPlayKitSettings>();
MutableSettings->DefaultChatModel = TEXT("gpt-4o-mini");
MutableSettings->SaveConfig();

Settings Categories

CategorySettings
GeneralGame ID, Base URL
AuthenticationDeveloper Token
ModelsDefault Chat Model, Default Image Model, Default STT Model
AdvancedRequest Timeout, Enable Logging

Error Handling

Error Types

The SDK defines common error types:

UENUM(BlueprintType)
enum class EPlayKitError : uint8
{
    None,
    NetworkError,
    AuthenticationError,
    InvalidRequest,
    RateLimited,
    InsufficientCredits,
    ServerError,
    Unknown
};

Handling Errors

ChatClient->Chat(
    Message,
    SystemPrompt,
    FOnChatComplete::CreateLambda([](const FString& Response, bool bSuccess)
    {
        if (!bSuccess)
        {
            // Response contains error message
            UE_LOG(LogTemp, Error, TEXT("Chat failed: %s"), *Response);
        }
    })
);

Insufficient Credits

Listen for UPlayKitPlayerClient::OnError and check the error message, or monitor the GetCredits() value and direct players to your game's recharge flow when it drops below your threshold.

Thread Safety

The SDK is designed for use on the game thread:

  • All callbacks are executed on the game thread
  • Client instances should be created and used on the game thread
  • HTTP requests are handled asynchronously but responses are marshaled back

Do not create or use PlayKit clients from background threads. Use Unreal's task system if you need async initialization.

Next Steps