Docs/SDKs/Unreal Engine

Unreal Engine

Official Unreal Engine SDK for Ilara. Supports UE 5.0+ with both C++ and Blueprint access.

15 min read
Requirements
  • Unreal Engine 5.0 or newer
  • C++ project (Blueprint-only projects need C++ enabled)

Installation

Method 1: Copy to Project (Recommended)

bash
# Clone the SDK to your Plugins folder
git clone https:class=class="code-string">"code-comment">//github.com/ilara/unreal-sdk.git YourProject/Plugins/Ilara
 
# Regenerate project files
# In Unreal Editor: File > Generate Visual Studio Project Files
 
# Enable the plugin
# Edit > Plugins > Search class="code-string">"Ilara" > Enable

Method 2: Engine Plugin

For use across multiple projects, copy to your engine installation:

bash
cp -r Ilara Engine/Plugins/Marketplace/Ilara

Configuration

Configure in Project Settings → Plugins → Ilara:

SettingDescriptionDefault
API KeyYour Ilara API key (pk_live_xxx or pk_test_xxx)(required)
Game IDOptional game ID override(auto-generated)
Base URLAPI endpointhttps://api.ilara.ai
Enable Debug LoggingShow SDK logsfalse
Auto Track SessionsTrack session start/endtrue
Event Batch SizeEvents per batch50
Event Flush IntervalSeconds between sends30
Code Configuration
cpp
UIlaraSubsystem* Ilara = GetGameInstance()->GetSubsystem();
Ilara->InitializeWithConfig(
TEXT(class="code-string">"pk_live_your_api_key"),
TEXT(class="code-string">""), class=class="code-string">"code-comment">// Game ID(optional)
TEXT(class="code-string">"") class=class="code-string">"code-comment">// Base URL(optional)
);

Quick Start

C++ Quick Start
cpp
#include class="code-string">"IlaraSubsystem.h"
 
void AMyGameMode::BeginPlay()
{
Super::BeginPlay();
 
class=class="code-string">"code-comment">// Get the Ilara subsystem
UIlaraSubsystem* Ilara = GetGameInstance()->GetSubsystem();
 
class=class="code-string">"code-comment">// Initialize(uses Project Settings)
Ilara->InitializeIlara();
 
class=class="code-string">"code-comment">// Bind to events
Ilara->OnPlayerIdentified.AddDynamic(this, &AMyGameMode::OnPlayerIdentified);
Ilara->OnError.AddDynamic(this, &AMyGameMode::OnIlaraError);
 
class=class="code-string">"code-comment">// Identify the player
TMap Attributes;
Attributes.Add(TEXT(class="code-string">"level"), TEXT(class="code-string">"5"));
Attributes.Add(TEXT(class="code-string">"country"), TEXT(class="code-string">"US"));
 
Ilara->IdentifyPlayer(
TEXT(class="code-string">"player_123"),
Attributes,
TEXT(class="code-string">"device_abc"), class=class="code-string">"code-comment">// Optional device ID
TEXT(class="code-string">"") class=class="code-string">"code-comment">// Optional email
);
}
 
void AMyGameMode::OnPlayerIdentified(const FIlaraPlayerData& PlayerData)
{
UE_LOG(LogTemp, Log, TEXT(class="code-string">"Player ID: %s"), *PlayerData.Id);
UE_LOG(LogTemp, Log, TEXT(class="code-string">"Lifecycle: %s"),
*UEnum::GetValueAsString(PlayerData.LifecycleStage));
}
 
void AMyGameMode::OnIlaraError(const FString& ErrorMessage)
{
UE_LOG(LogTemp, Error, TEXT(class="code-string">"Ilara Error: %s"), *ErrorMessage);
}

Blueprint Usage

  1. Get the Ilara Subsystem using "Get Game Instance" → "Get Subsystem" → "Ilara Subsystem"
  2. Call "Initialize Ilara"
  3. Call "Identify Player" with your player ID
  4. Use "Track Event" to log events

Event Tracking

Track Events
cpp
UIlaraSubsystem* Ilara = GetGameInstance()->GetSubsystem();
 
class=class="code-string">"code-comment">// Track single event
TMap Props;
Props.Add(TEXT(class="code-string">"level"), TEXT(class="code-string">"5"));
Props.Add(TEXT(class="code-string">"score"), TEXT(class="code-string">"1500"));
Ilara->TrackEvent(TEXT(class="code-string">"level_complete"), Props);
 
class=class="code-string">"code-comment">// Track with session ID
Ilara->TrackEvent(TEXT(class="code-string">"level_start"), Props, TEXT(class="code-string">"session_001"));
 
class=class="code-string">"code-comment">// Batch events(for manual batching)
TArray Events;
FIlaraEvent Event1;
Event1.PlayerId = Ilara->GetCurrentPlayerId();
Event1.EventName = TEXT(class="code-string">"coin_collect");
Event1.Properties.Add(TEXT(class="code-string">"amount"), TEXT(class="code-string">"100"));
Events.Add(Event1);
Ilara->TrackEventsBatch(Events);
 
class=class="code-string">"code-comment">// Force flush pending events
Ilara->FlushEvents();

Feature Flags

Check Flags
cpp
UIlaraSubsystem* Ilara = GetGameInstance()->GetSubsystem();
 
class=class="code-string">"code-comment">// Get all flags(SDK bootstrap)
Ilara->GetAllFlags();
 
class=class="code-string">"code-comment">// Evaluate specific flag
Ilara->EvaluateFlag(TEXT(class="code-string">"new_tutorial"));
 
class=class="code-string">"code-comment">// Check cached boolean flag
if (Ilara->IsFlagEnabled(TEXT(class="code-string">"double_xp"), false))
{
ApplyDoubleXP();
}
 
class=class="code-string">"code-comment">// Get cached flag value
FString Variant = Ilara->GetFlagValue(TEXT(class="code-string">"checkout_flow"), TEXT(class="code-string">"control"));

Data Types

FIlaraPlayerData

cpp
USTRUCT(BlueprintType)
struct FIlaraPlayerData
{
FString Id; class=class="code-string">"code-comment">// Ilara UUID
FString ExternalId; class=class="code-string">"code-comment">// Your player ID
FString DeviceId;
FString Email;
EIlaraLifecycleStage LifecycleStage; class=class="code-string">"code-comment">// new, active, engaged, at_risk, churned, returned
int32 SessionCount;
float TotalRevenue;
bool bIsPayer;
TMap Attributes;
};

FIlaraChurnRisk

cpp
USTRUCT(BlueprintType)
struct FIlaraChurnRisk
{
FString PlayerId;
float RiskScore; class=class="code-string">"code-comment">// 0.0 - 1.0
EIlaraChurnRiskLevel RiskLevel; class=class="code-string">"code-comment">// Low, Medium, High
TArray Factors;
 
bool IsAtRisk() const; class=class="code-string">"code-comment">// True if Medium or High
};

FIlaraFlagEvaluation

cpp
USTRUCT(BlueprintType)
struct FIlaraFlagEvaluation
{
FString FlagKey;
FString Value;
FString VariantKey;
FString Reason;
 
bool GetBoolValue() const;
int32 GetIntValue() const;
float GetFloatValue() const;
};

Events & Delegates

Bind to Delegates
cpp
class=class="code-string">"code-comment">// SDK initialized
Ilara->OnInitialized.AddDynamic(this, &AMyClass::OnInitialized);
 
class=class="code-string">"code-comment">// Player identified
Ilara->OnPlayerIdentified.AddDynamic(this, &AMyClass::OnPlayerIdentified);
void OnPlayerIdentified(const FIlaraPlayerData& PlayerData);
 
class=class="code-string">"code-comment">// Event tracked
Ilara->OnEventTracked.AddDynamic(this, &AMyClass::OnEventTracked);
void OnEventTracked(const FString& EventName);
 
class=class="code-string">"code-comment">// Error occurred
Ilara->OnError.AddDynamic(this, &AMyClass::OnError);
void OnError(const FString& ErrorMessage);

Best Practices

  • Initialize Early: Call InitializeIlara() in GameInstance's Init() or GameMode's BeginPlay()
  • Identify Before Tracking: Always call IdentifyPlayer() before tracking events
  • Use Auto Session Tracking: Enable in settings for automatic session recording
  • Batch Events: Use reasonable batch size (50-100) for optimal performance
  • Handle Errors: Always bind to OnError delegate
  • Use Cached Flags: Call GetAllFlags() at startup, then use IsFlagEnabled()

Development Mode

Local Development
cpp
Ilara->InitializeWithConfig(
TEXT(class="code-string">"pk_test_xxx"),
TEXT(class="code-string">""),
TEXT(class="code-string">"http:class="code-commentclass="code-string">">//localhost:18000/v1")
);

Troubleshooting

SDK Not Initializing

  • Check API Key is set in Project Settings
  • Verify network connectivity
  • Enable debug logging to see detailed errors

Events Not Tracking

  • Ensure player is identified first
  • Check batch settings—events batch before sending
  • Call FlushEvents() to force send

Flags Not Working

  • Call GetAllFlags() to bootstrap
  • Check that flags exist in Ilara dashboard
  • Verify player is in targeting rules

Support