Version 1.34.2 | Production Ready | Unreal Engine 5.5+
The Persistent Map is a production-ready actor-based persistence system that manages the saving and loading of actors to/from Supabase with advanced batch processing, error recovery, and monitoring capabilities.
The APersistentMap actor provides enterprise-level persistence functionality for Unreal Engine projects using Supabase as the backend. It offers sophisticated batch operations, intelligent retry logic, and comprehensive monitoring for production environments.
UCLASS(BlueprintType)
class SUPABASE_API APersistentMap : public AActor
The system consists of three main components:
USTRUCT(BlueprintType)
struct FPersistentMapStats
{
int32 TotalActors;
int32 SavedActors;
int32 LoadedActors;
int32 FailedActors;
FDateTime LastOperation;
FString LastOperationType;
bool bOperationInProgress;
};
// Spawn and configure PersistentMap
APersistentMap* PersistentMap = GetWorld()->SpawnActor<APersistentMap>();
PersistentMap->SetConnection(MySupabaseConnection);
PersistentMap->SetTableName(TEXT("my_persistent_actors"));
| Property | Type | Default | Description |
|---|---|---|---|
Connection |
USupabaseConnection* |
nullptr |
Supabase connection reference |
TableName |
FString |
"persistent_actors" |
Database table name |
bAutoSaveEnabled |
bool |
false |
Enable automatic saving |
AutoSaveInterval |
float |
300.0f |
Auto-save interval in seconds |
BatchSize |
int32 |
20 |
Number of actors per batch |
bEnableValidation |
bool |
true |
Enable data validation |
bVerboseLogging |
bool |
false |
Enable detailed logging |
// Save all actors with EntityPersistence components
PersistentMap->SaveActorsToSupabase();
// Load actors from database (clear existing)
PersistentMap->LoadActorsFromSupabase(true);
// Sync operation (load then save)
PersistentMap->SyncActorsWithSupabase();
// Enable auto-save with 5-minute intervals
PersistentMap->EnableAutoSave(true, 300.0f);
// Disable auto-save
PersistentMap->EnableAutoSave(false, 0.0f);
// Save to local JSON file
PersistentMap->SaveActorsToFile("MyActors.json");
// Load from local JSON file
PersistentMap->LoadActorsFromFile("MyActors.json");
// Get current statistics
FPersistentMapStats Stats = PersistentMap->GetStats();
UE_LOG(LogTemp, Log, TEXT("Total Actors: %d, Saved: %d, Failed: %d"),
Stats.TotalActors, Stats.SavedActors, Stats.FailedActors);
// Reset statistics
PersistentMap->ResetStats();
The Persistent Map provides comprehensive event handling through Blueprint-assignable delegates:
// Save operation completed
UPROPERTY(BlueprintAssignable)
FOnPersistentMapOperation OnSaveComplete;
// Load operation completed with actor details
UPROPERTY(BlueprintAssignable)
FOnActorsLoaded OnLoadComplete;
// Sync operation completed
UPROPERTY(BlueprintAssignable)
FOnPersistentMapOperation OnSyncComplete;
// Error occurred during operation
UPROPERTY(BlueprintAssignable)
FOnPersistentMapOperation OnError;
UFUNCTION(BlueprintCallable, Category = "Supabase|Persistence")
void SaveActorsToSupabase(bool bForceSync = false);
UFUNCTION(BlueprintCallable, Category = "Supabase|Persistence")
void LoadActorsFromSupabase(bool bClearExisting = true);
UFUNCTION(BlueprintCallable, Category = "Supabase|Persistence")
void SyncActorsWithSupabase();
USTRUCT(BlueprintType)
struct FActorData
{
FString ActorID; // Unique identifier
FTransform Transform; // World transform
TMap<FString, FString> CustomData; // Custom properties
FString LevelName; // Source level
TSoftClassPtr<AActor> ActorClass; // Actor class reference
};
The Persistent Map expects a Supabase table with the following structure:
CREATE TABLE persistent_actors (
id SERIAL PRIMARY KEY,
actor_id TEXT UNIQUE NOT NULL,
transform JSONB NOT NULL,
custom_data JSONB,
level_name TEXT,
actor_class TEXT,
saved_at TIMESTAMP DEFAULT NOW(),
created_at TIMESTAMP DEFAULT NOW()
);
#if WITH_EDITOR
UFUNCTION(BlueprintCallable, CallInEditor)
void FetchAllActorsWithEntityPersistence();
UFUNCTION(BlueprintCallable, CallInEditor)
void TestSaveToFile();
UFUNCTION(BlueprintCallable, CallInEditor)
void ValidateAllActors();
#endif
The system provides comprehensive validation:
The Persistent Map works seamlessly with the EntityPersistence component:
// Automatically detects EntityPersistence components
if (UEntityPersistence* EntityPersistence = Actor->FindComponentByClass<UEntityPersistence>())
{
ActorData.CustomData.Add(TEXT("HasEntityPersistence"), TEXT("true"));
}
| Issue | Cause | Solution |
|---|---|---|
| Save operations fail | Invalid connection | Check Supabase connection configuration |
| Actors not loading | Table schema mismatch | Verify database table structure |
| Memory leaks | Timer not cleared | Ensure proper EndPlay cleanup |
| Performance issues | Large batch sizes | Reduce batch size configuration |
Enable verbose logging for detailed operation tracking:
// Enable in constructor or BeginPlay
bVerboseLogging = true;
// Check connection status
bool bIsValid = PersistentMap->ValidateConnection();
UE_LOG(LogTemp, Log, TEXT("Connection Valid: %s"), bIsValid ? TEXT("Yes") : TEXT("No"));
This documentation is part of the Seven Mountains Labs Supabase UE5 Plugin wiki. For the latest updates and community support, visit our documentation portal.