Core Concepts
Understand the core architecture and design patterns of PlayKit Unity SDK
Core Concepts
SDK Architecture
The PlayKit Unity SDK uses a modular design with the following core components:
- PlayKitSDK: The SDK entry point, using singleton pattern to manage global configuration and initialization
- Client Factory: Creates different types of AI clients through factory methods
- Service Providers: Handle communication with the PlayKit API
- Authentication Manager: Manages developer and player identity authentication
Singleton Pattern
PlayKitSDK uses the singleton pattern to ensure only one SDK instance exists throughout the application. You can access the instance via PlayKitSDK.Instance, but in most cases static methods are sufficient:
await PlayKitSDK.InitializeAsync();
bool isReady = PlayKitSDK.IsReady();
var playerClient = PlayKitSDK.GetPlayerClient();The SDK auto-initializes at runtime using [RuntimeInitializeOnLoadMethod] — no prefab placement required.
Client Types
The SDK provides multiple clients to handle different AI features:
PlayKit_AIChatClient
Used for AI text generation and conversation. Supports basic chat, streaming responses, and structured output.
var chatClient = PlayKitSDK.Factory.CreateChatClient();
var chatClient = PlayKitSDK.Factory.CreateChatClient("gpt-4o");Learn more: Text Generation
PlayKit_AIImageClient
Used for AI image generation. Supports multiple sizes and aspect ratios.
var imageClient = PlayKitSDK.Factory.CreateImageClient();
var imageClient = PlayKitSDK.Factory.CreateImageClient("dall-e-3");Learn more: Image Generation
PlayKit_AudioTranscriptionClient
Used for converting audio to text (speech recognition).
var transcriptionClient = PlayKitSDK.Factory.CreateTranscriptionClient("whisper-1");Learn more: Speech Recognition
PlayKit_NPC
A specialized client for simplifying NPC dialogue. Used as a MonoBehaviour component, automatically manages conversation history.
var npc = gameObject.AddComponent<PlayKit_NPC>();
PlayKitSDK.Populate.CreateNpc(recipient, "gpt-4o");Learn more: NPC Conversations
PlayKit_PlayerClient
Manages player information, authentication, and credits.
var playerClient = PlayKitSDK.GetPlayerClient();
var info = playerClient.GetCachedPlayerInfo();
Debug.Log($"Remaining credits: {info.Credits}");Learn more: Authentication
PlayKit_AIChatClient vs PlayKit_NPC
The SDK gives you two ways to build AI conversations. Picking the right one avoids a lot of unnecessary wiring.
PlayKit_AIChatClient — developer-facing
PlayKit_AIChatClient is a low-level building block. It exposes exactly what you need and nothing more: you hand it a message list, it returns a response. History, parsing, and output format are entirely yours to own.
var chatClient = PlayKitSDK.Factory.CreateChatClient();
var config = new PlayKit_ChatConfig(messages) { Temperature = 0.7f };
var result = await chatClient.TextGenerationAsync(config, token);
// you decide what to do with result.ResponseUse it for: custom chat UIs, in-game consoles, structured data generation (GenerateStructuredAsync), tool/function calling, or any pipeline where you control the shape of the conversation.
PlayKit_NPC — game-designer-facing
PlayKit_NPC is an opinionated game-character system. You write a SetCharacterDesign() prompt; the SDK handles history, memory, reply predictions, and voice integration. The API surface is deliberately small so a designer can configure it without touching engine code.
npc.SetCharacterDesign("You are a gruff blacksmith named Arn...");
string reply = await npc.Talk("I need a sword", token);Use it for: interactive NPCs, companion characters, dialogue scenes.
Why NPC uses Actions instead of structured output
PlayKit_NPC has no structured output method by design. The alternative is the Actions system, for two reasons:
Speed. Structured output adds tokens and a post-processing step — the model must produce valid JSON before anything happens in-game. Actions are embedded inline in the dialogue and execute the moment the model signals them, with no parsing overhead.
Character integrity. A structured-output call produces a JSON object, not a sentence — the character voice breaks. Actions let the NPC speak naturally and trigger game logic in the same response, without exposing a data format to the player.
// What the NPC can do is registered in the inspector or in code:
npc.OnActionTriggered += (actionName, args) => {
if (actionName == "GiveItem") GiveItemToPlayer(args["item_name"]);
if (actionName == "OpenShop") OpenShopUI();
};
// The NPC decides when to call them while replying naturally.For structured data that lives outside the character (item stats, quest definitions, world state reads), use PlayKit_AIChatClient.GenerateStructuredAsync — not the NPC component.
At a glance
PlayKit_AIChatClient | PlayKit_NPC | |
|---|---|---|
| Audience | Developers | Game designers |
| History | Manual | Automatic |
| Output | Raw string / typed object | Natural dialogue + action calls |
| Structured data | GenerateStructuredAsync | Use Actions instead |
| Game logic integration | Parse response manually | Action system |
| Memory | — | SetMemory / GetMemory |
| Save / restore | — | SaveHistory / LoadHistory |
Factory Pattern
The SDK uses the factory pattern to create client instances. Factory methods are located in PlayKitSDK.Factory and PlayKitSDK.Populate:
var chat = PlayKitSDK.Factory.CreateChatClient();
var chat = PlayKitSDK.Factory.CreateChatClient("gpt-4o");
var image = PlayKitSDK.Factory.CreateImageClient();
var transcription = PlayKitSDK.Factory.CreateTranscriptionClient("whisper-1");
PlayKitSDK.Populate.CreateNpc(npcComponent, "gpt-4o");If you don't specify a model name, the SDK will use the default model configured in the PlayKit SDK Settings window.
Async Operations
All SDK API calls are asynchronous, based on UniTask. UniTask is a Unity-optimized async library that's more efficient than standard Task.
Using async/await
using Cysharp.Threading.Tasks;
async void Start()
{
var chatClient = PlayKitSDK.Factory.CreateChatClient();
var result = await chatClient.TextGenerationAsync(
config,
this.GetCancellationTokenOnDestroy()
);
if (result.Success)
{
Debug.Log(result.Response);
}
}CancellationToken
All async methods accept a CancellationToken parameter for cancelling ongoing operations:
// Automatically cancel using Unity lifecycle
await chatClient.TextGenerationAsync(config, this.GetCancellationTokenOnDestroy());
// Manual cancellation control
var cts = new CancellationTokenSource();
var task = chatClient.TextGenerationAsync(config, cts.Token);
// Cancel after 5 seconds
await UniTask.Delay(5000);
cts.Cancel();When using async operations in Unity, always pass a CancellationToken to avoid continuing execution after object destruction.
Conversation Message System
AI conversations use a message list to maintain context. Each message contains a Role and Content.
Message Roles
The SDK supports three message roles:
- system: System instructions that define AI behavior and role
- user: User or player messages
- assistant: AI responses
Creating Conversation History
var messages = new List<PlayKit_ChatMessage>
{
new PlayKit_ChatMessage
{
Role = "system",
Content = "You are a friendly game NPC named Ellie. You run a magic shop."
},
new PlayKit_ChatMessage
{
Role = "user",
Content = "Hello, what do you sell?"
},
new PlayKit_ChatMessage
{
Role = "assistant",
Content = "Welcome! I have various magic potions and scrolls."
},
new PlayKit_ChatMessage
{
Role = "user",
Content = "Do you have healing potions?"
}
};
var config = new PlayKit_ChatConfig(messages) { Temperature = 0.7f };
var result = await chatClient.TextGenerationAsync(config, cancellationToken);Managing Conversation History
You need to manually maintain conversation history, or use PlayKit_NPC for automatic management:
var history = new List<PlayKit_ChatMessage>
{
new PlayKit_ChatMessage { Role = "system", Content = "You are a friendly assistant." },
new PlayKit_ChatMessage { Role = "user", Content = "Hello" }
};
var result = await chatClient.TextGenerationAsync(new PlayKit_ChatConfig(history), token);
if (result.Success)
{
history.Add(new PlayKit_ChatMessage { Role = "assistant", Content = result.Response });
}Using PlayKit_NPC automatically manages conversation history without manual message adding.
Result Wrapper
The SDK uses PlayKit_AIResult<T> type to wrap API call results:
public class PlayKit_AIResult<T>
{
public bool Success { get; } // Whether operation succeeded
public T Response { get; } // Response data
public string ErrorMessage { get; } // Error message (if failed)
}Handling Results
var result = await chatClient.TextGenerationAsync(config, token);
if (result.Success)
{
// Success: use result.Response
Debug.Log($"AI response: {result.Response}");
DisplayMessage(result.Response);
}
else
{
// Failure: check result.ErrorMessage
Debug.LogError($"Call failed: {result.ErrorMessage}");
ShowErrorDialog(result.ErrorMessage);
}Error Handling
The SDK provides clear error handling mechanisms.
Using Result Checking
The recommended approach is checking the PlayKit_AIResult's Success property:
var result = await chatClient.TextGenerationAsync(config, token);
if (!result.Success)
{
Debug.LogError($"Error: {result.ErrorMessage}");
}Catching Exceptions
For severe errors, the SDK throws exceptions:
using PlayKit_SDK;
using PlayKit_SDK.Public;
try
{
var result = await chatClient.TextGenerationAsync(config, token);
}
catch (PlayKitApiErrorException ex)
{
Debug.LogError($"API error: {ex.Message}");
}
catch (PlayKitImageSizeValidationException ex)
{
Debug.LogError($"Invalid image size: {ex.Message}");
}
catch (PlayKitException ex)
{
Debug.LogError($"SDK error: {ex.Message}");
}Common Errors
- SDK not initialized: Calling API before calling
InitializeAsync() - Invalid Token: Developer Token expired or incorrect
- Network error: Cannot connect to PlayKit API
- Insufficient credits: Player account has insufficient credits
- Parameter error: Invalid parameters passed (e.g., unsupported image size)
Configuration Options
Temperature
The temperature parameter controls AI response randomness, ranging from 0.0 to 2.0:
- 0.0-0.3: High determinism, suitable for factual answers
- 0.7: Balance creativity and consistency (default)
- 1.5-2.0: Highly creative, suitable for creative content
var config = new PlayKit_ChatConfig(messages) { Temperature = 0.7f };Default Models
You can configure default models in the PlayKit SDK Settings window:
- Default Chat Model: Default chat model
- Default Image Model: Default image generation model
Factory methods will use these defaults if no model is specified.
Debug Tools
The SDK provides some debugging helper methods:
Print Conversation History
PlayKit_AIChatClient.PrintPrettyChatMessages(messages, "Current Conversation");Check SDK Status
if (PlayKitSDK.IsReady())
{
Debug.Log("SDK is ready");
}
else
{
Debug.LogWarning("SDK not initialized");
}NPC Debugging
var npc = GetComponent<PlayKit_NPC>();
// Print NPC conversation history
npc.PrintPrettyChatMessages("NPC History");
// Check status
Debug.Log($"Is talking: {npc.IsTalking}");
Debug.Log($"History message count: {npc.GetHistoryLength()}");Best Practices
- Always check IsReady(): Ensure SDK is initialized before calling APIs
- Use CancellationToken: Avoid continuing async operations after object destruction
- Check Success: Always check
PlayKit_AIResult.Successinstead of assuming success - Limit history length: Long conversation history increases API costs and response time
- Set temperature appropriately: Choose suitable temperature values for your use case
- Use NPC Client: For game characters, prefer
PlayKit_NPCover manual history management
Next Steps
Now that you understand the SDK's core concepts, continue learning specific features:
- Text Generation - Implement AI conversations
- NPC Conversations - Create intelligent NPCs
- Image Generation - Generate AI images
- Speech Recognition - Speech to text