< All Topics

Array Compression Functions (deflate)

Overview

The Compress array (deflate) and Decompress array (deflate) functions provide high-performance data compression and decompression for byte arrays using the deflate algorithm. These functions are perfect for reducing memory usage, network transmission, and storage requirements for large data sets.

Function Descriptions

Compress Array (deflate)

  • Node Name: Compress array (deflate)
  • Category: Archive Manager
  • Type: Synchronous (immediate operation)

Compresses a byte array using the deflate compression algorithm, returning the compressed data along with the original size for decompression reference.

Decompress Array (deflate)

  • Node Name: Decompress array (deflate)
  • Category: Archive Manager
  • Type: Synchronous (immediate operation)

Decompresses a previously compressed byte array back to its original form using the original size information.

Blueprint Usage

Compress Array (deflate) Parameters

ParameterTypeDescription
InputArray of BytesThe original byte array to compress
OutputTypeDescription
OutputArray of BytesThe compressed byte array
Original SizeIntegerSize of the original data (needed for decompression)
Return ValueBooleantrue if compression succeeded, false if failed

Decompress Array (deflate) Parameters

ParameterTypeDescription
InputArray of BytesThe compressed byte array to decompress
Original SizeIntegerSize of the original uncompressed data
OutputTypeDescription
OutputArray of BytesThe decompressed byte array (original data)
Return ValueBooleantrue if decompression succeeded, false if failed

Blueprint Setup Example

Example compression/Decompression Workflow

  1. Create Test Data: Use “Create random data” node to generate sample data
    • Set Size: 1000 (creates 1000 bytes of random data)
  2. Display Original Size: Connect to Print String to show original data size
  3. Compress Data: Add “Compress array (deflate)” node
    • Connect random data array to Input
    • Store the Original Size output for later decompression
  4. Display Compression Results: Show compressed size and compression ratio
  5. Decompress Data: Add “Decompress array (deflate)” node
    • Connect compressed Output to Input
    • Connect stored Original Size to Original Size parameter
  6. Verify Results: Display decompressed data size to confirm successful round-trip

C++ Usage

Basic Compression / Decompression

void BasicCompressionExample()
{
    // Create some test data
    TArray<uint8> OriginalData;
    FString TestString = TEXT("Hello World! This is a test string for compression.");
    
    // Convert string to byte array
    FTCHARToUTF8 Converter(*TestString);
    OriginalData.Append((uint8*)Converter.Get(), Converter.Length());
    
    // Compress the data
    TArray<uint8> CompressedData;
    int32 OriginalSize;
    
    bool bCompressionSuccess = UArchiveManagerBPLibrary::CompressArray(
        OriginalData, 
        CompressedData, 
        OriginalSize
    );
    
    if (bCompressionSuccess)
    {
        UE_LOG(LogTemp, Log, TEXT("Compression successful. Original: %d bytes, Compressed: %d bytes"), 
               OriginalSize, CompressedData.Num());
        
        // Calculate compression ratio
        float CompressionRatio = (float)CompressedData.Num() / (float)OriginalSize;
        UE_LOG(LogTemp, Log, TEXT("Compression ratio: %.2f (%.1f%% savings)"), 
               CompressionRatio, (1.0f - CompressionRatio) * 100.0f);
        
        // Decompress the data
        TArray<uint8> DecompressedData;
        bool bDecompressionSuccess = UArchiveManagerBPLibrary::DecompressArray(
            CompressedData, 
            OriginalSize, 
            DecompressedData
        );
        
        if (bDecompressionSuccess)
        {
            UE_LOG(LogTemp, Log, TEXT("Decompression successful. Size: %d bytes"), 
                   DecompressedData.Num());
            
            // Verify data integrity
            if (DecompressedData.Num() == OriginalData.Num())
            {
                bool bDataMatches = true;
                for (int32 i = 0; i < OriginalData.Num(); i++)
                {
                    if (OriginalData[i] != DecompressedData[i])
                    {
                        bDataMatches = false;
                        break;
                    }
                }
                
                if (bDataMatches)
                {
                    UE_LOG(LogTemp, Log, TEXT("✅ Data integrity verified - round-trip successful!"));
                }
                else
                {
                    UE_LOG(LogTemp, Error, TEXT("❌ Data integrity check failed!"));
                }
            }
        }
        else
        {
            UE_LOG(LogTemp, Error, TEXT("❌ Decompression failed!"));
        }
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("❌ Compression failed!"));
    }
}
Network Data Compression System

UCLASS()
class YOURGAME_API UNetworkCompressionManager : public UObject
{
    GENERATED_BODY()

public:
    UFUNCTION(BlueprintCallable)
    TArray<uint8> CompressForNetwork(const TArray<uint8>& Data, int32& OutOriginalSize);
    
    UFUNCTION(BlueprintCallable)
    TArray<uint8> DecompressFromNetwork(const TArray<uint8>& CompressedData, int32 OriginalSize);
    
    UFUNCTION(BlueprintCallable)
    float GetCompressionRatio(int32 OriginalSize, int32 CompressedSize);
    
    UFUNCTION(BlueprintCallable)
    bool ShouldCompressData(int32 DataSize, float MinCompressionRatio = 0.8f);
};

TArray<uint8> UNetworkCompressionManager::CompressForNetwork(const TArray<uint8>& Data, int32& OutOriginalSize)
{
    TArray<uint8> CompressedData;
    
    // Only compress if data is large enough to benefit
    if (Data.Num() < 100)
    {
        UE_LOG(LogTemp, Log, TEXT("Data too small for compression (%d bytes), sending uncompressed"), Data.Num());
        OutOriginalSize = Data.Num();
        return Data;
    }
    
    bool bSuccess = UArchiveManagerBPLibrary::CompressArray(Data, CompressedData, OutOriginalSize);
    
    if (bSuccess)
    {
        float CompressionRatio = GetCompressionRatio(OutOriginalSize, CompressedData.Num());
        
        // Only use compressed data if it's actually smaller
        if (CompressionRatio < 0.95f) // At least 5% savings
        {
            UE_LOG(LogTemp, Log, TEXT("Network compression: %.2f%% size reduction (%d -> %d bytes)"), 
                   (1.0f - CompressionRatio) * 100.0f, OutOriginalSize, CompressedData.Num());
            return CompressedData;
        }
        else
        {
            UE_LOG(LogTemp, Log, TEXT("Compression not beneficial (%.2f ratio), sending uncompressed"), CompressionRatio);
        }
    }
    else
    {
        UE_LOG(LogTemp, Warning, TEXT("Compression failed, sending uncompressed data"));
    }
    
    OutOriginalSize = Data.Num();
    return Data; // Return original if compression failed or wasn't beneficial
}

TArray<uint8> UNetworkCompressionManager::DecompressFromNetwork(const TArray<uint8>& CompressedData, int32 OriginalSize)
{
    // If sizes match, data wasn't compressed
    if (CompressedData.Num() == OriginalSize)
    {
        UE_LOG(LogTemp, Log, TEXT("Data wasn't compressed, returning as-is"));
        return CompressedData;
    }
    
    TArray<uint8> DecompressedData;
    bool bSuccess = UArchiveManagerBPLibrary::DecompressArray(CompressedData, OriginalSize, DecompressedData);
    
    if (bSuccess)
    {
        UE_LOG(LogTemp, Log, TEXT("Network decompression successful: %d -> %d bytes"), 
               CompressedData.Num(), DecompressedData.Num());
        return DecompressedData;
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("Network decompression failed! Returning empty array"));
        return TArray<uint8>();
    }
}

float UNetworkCompressionManager::GetCompressionRatio(int32 OriginalSize, int32 CompressedSize)
{
    return OriginalSize > 0 ? (float)CompressedSize / (float)OriginalSize : 1.0f;
}

bool UNetworkCompressionManager::ShouldCompressData(int32 DataSize, float MinCompressionRatio)
{
    // Don't compress very small data
    if (DataSize < 100) return false;
    
    // For this example, we assume compression will be beneficial for larger data
    // In practice, you might want to test compression on a sample first
    return DataSize > 500;
}
Save Game Compression System

UCLASS()
class YOURGAME_API UCompressedSaveGame : public USaveGame
{
    GENERATED_BODY()

public:
    UPROPERTY(SaveGame)
    TArray<uint8> CompressedGameData;
    
    UPROPERTY(SaveGame)
    int32 OriginalDataSize;
    
    UPROPERTY(SaveGame)
    bool bIsCompressed;
    
    UPROPERTY(SaveGame)
    FString SaveVersion;
    
    UPROPERTY(SaveGame)
    FDateTime SaveTime;
    
    // Compress and store game data
    UFUNCTION(BlueprintCallable)
    bool CompressAndStore(const TArray<uint8>& GameData);
    
    // Decompress and retrieve game data
    UFUNCTION(BlueprintCallable)
    bool DecompressAndRetrieve(TArray<uint8>& OutGameData);
    
    // Get compression statistics
    UFUNCTION(BlueprintCallable)
    FString GetCompressionStats();
};

bool UCompressedSaveGame::CompressAndStore(const TArray<uint8>& GameData)
{
    SaveTime = FDateTime::Now();
    SaveVersion = TEXT("1.0");
    
    // Try to compress the data
    bool bSuccess = UArchiveManagerBPLibrary::CompressArray(
        GameData, 
        CompressedGameData, 
        OriginalDataSize
    );
    
    if (bSuccess)
    {
        // Check if compression was beneficial
        float CompressionRatio = (float)CompressedGameData.Num() / (float)OriginalDataSize;
        
        if (CompressionRatio < 0.9f) // At least 10% savings
        {
            bIsCompressed = true;
            UE_LOG(LogTemp, Log, TEXT("Save game compressed: %d -> %d bytes (%.1f%% savings)"), 
                   OriginalDataSize, 
                   CompressedGameData.Num(),
                   (1.0f - CompressionRatio) * 100.0f);
        }
        else
        {
            // Store uncompressed if compression wasn't beneficial
            bIsCompressed = false;
            CompressedGameData = GameData;
            UE_LOG(LogTemp, Log, TEXT("Save game stored uncompressed (compression not beneficial)"));
        }
    }
    else
    {
        // Store uncompressed if compression failed
        bIsCompressed = false;
        CompressedGameData = GameData;
        OriginalDataSize = GameData.Num();
        UE_LOG(LogTemp, Warning, TEXT("Compression failed, storing uncompressed save data"));
    }
    
    return true; // Always succeed in storing, even if compression failed
}

bool UCompressedSaveGame::DecompressAndRetrieve(TArray<uint8>& OutGameData)
{
    if (!bIsCompressed)
    {
        // Data wasn't compressed, return as-is
        OutGameData = CompressedGameData;
        UE_LOG(LogTemp, Log, TEXT("Save game wasn't compressed, returning %d bytes"), OutGameData.Num());
        return true;
    }
    
    // Decompress the data
    bool bSuccess = UArchiveManagerBPLibrary::DecompressArray(
        CompressedGameData, 
        OriginalDataSize, 
        OutGameData
    );
    
    if (bSuccess)
    {
        UE_LOG(LogTemp, Log, TEXT("Save game decompressed: %d -> %d bytes"), 
               CompressedGameData.Num(), OutGameData.Num());
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("Save game decompression failed!"));
    }
    
    return bSuccess;
}

FString UCompressedSaveGame::GetCompressionStats()
{
    if (!bIsCompressed)
    {
        return FString::Printf(TEXT("Uncompressed: %d bytes"), CompressedGameData.Num());
    }
    
    float CompressionRatio = (float)CompressedGameData.Num() / (float)OriginalDataSize;
    float SavingsPercent = (1.0f - CompressionRatio) * 100.0f;
    
    return FString::Printf(TEXT("Compressed: %d -> %d bytes (%.1f%% savings)"), 
                          OriginalDataSize, CompressedGameData.Num(), SavingsPercent);
}
Asset Cache Compression
UCLASS()
class YOURGAME_API UAssetCacheManager : public UObject
{
    GENERATED_BODY()

private:
    struct FCachedAssetData
    {
        TArray<uint8> CompressedData;
        int32 OriginalSize;
        FString AssetPath;
        FDateTime CacheTime;
        bool bIsCompressed;
        
        FCachedAssetData()
            : OriginalSize(0)
            , bIsCompressed(false)
        {
        }
    };
    
    TMap<FString, FCachedAssetData> AssetCache;
    
public:
    UFUNCTION(BlueprintCallable)
    bool CacheAssetData(const FString& AssetPath, const TArray<uint8>& AssetData);
    
    UFUNCTION(BlueprintCallable)
    bool RetrieveAssetData(const FString& AssetPath, TArray<uint8>& OutAssetData);
    
    UFUNCTION(BlueprintCallable)
    void ClearCache();
    
    UFUNCTION(BlueprintCallable)
    TArray<FString> GetCachedAssetPaths();
    
    UFUNCTION(BlueprintCallable)
    FString GetCacheStats();
};

bool UAssetCacheManager::CacheAssetData(const FString& AssetPath, const TArray<uint8>& AssetData)
{
    FCachedAssetData CacheEntry;
    CacheEntry.AssetPath = AssetPath;
    CacheEntry.CacheTime = FDateTime::Now();
    
    // Try to compress the asset data
    bool bSuccess = UArchiveManagerBPLibrary::CompressArray(
        AssetData, 
        CacheEntry.CompressedData, 
        CacheEntry.OriginalSize
    );
    
    if (bSuccess)
    {
        float CompressionRatio = (float)CacheEntry.CompressedData.Num() / (float)CacheEntry.OriginalSize;
        
        // Only use compression if it's beneficial
        if (CompressionRatio < 0.8f) // At least 20% savings
        {
            CacheEntry.bIsCompressed = true;
            UE_LOG(LogTemp, Log, TEXT("Cached asset %s: %d bytes compressed to %d bytes (%.1f%% savings)"), 
                   *AssetPath, CacheEntry.OriginalSize, CacheEntry.CompressedData.Num(),
                   (1.0f - CompressionRatio) * 100.0f);
        }
        else
        {
            // Store uncompressed if compression wasn't beneficial
            CacheEntry.bIsCompressed = false;
            CacheEntry.CompressedData = AssetData;
            UE_LOG(LogTemp, Log, TEXT("Cached asset %s: stored uncompressed (%d bytes)"), 
                   *AssetPath, AssetData.Num());
        }
    }
    else
    {
        // Store uncompressed if compression failed
        CacheEntry.bIsCompressed = false;
        CacheEntry.CompressedData = AssetData;
        CacheEntry.OriginalSize = AssetData.Num();
        UE_LOG(LogTemp, Warning, TEXT("Compression failed for asset %s, storing uncompressed"), *AssetPath);
    }
    
    AssetCache.Add(AssetPath, CacheEntry);
    return true;
}

bool UAssetCacheManager::RetrieveAssetData(const FString& AssetPath, TArray<uint8>& OutAssetData)
{
    FCachedAssetData* CacheEntry = AssetCache.Find(AssetPath);
    if (!CacheEntry)
    {
        UE_LOG(LogTemp, Warning, TEXT("Asset %s not found in cache"), *AssetPath);
        return false;
    }
    
    if (!CacheEntry->bIsCompressed)
    {
        // Data wasn't compressed, return as-is
        OutAssetData = CacheEntry->CompressedData;
        UE_LOG(LogTemp, Log, TEXT("Retrieved uncompressed asset %s (%d bytes)"), 
               *AssetPath, OutAssetData.Num());
        return true;
    }
    
    // Decompress the cached data
    bool bSuccess = UArchiveManagerBPLibrary::DecompressArray(
        CacheEntry->CompressedData,
        CacheEntry->OriginalSize,
        OutAssetData
    );
    
    if (bSuccess)
    {
        UE_LOG(LogTemp, Log, TEXT("Retrieved and decompressed asset %s: %d -> %d bytes"), 
               *AssetPath, CacheEntry->CompressedData.Num(), OutAssetData.Num());
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("Failed to decompress cached asset %s"), *AssetPath);
    }
    
    return bSuccess;
}

void UAssetCacheManager::ClearCache()
{
    int32 NumCleared = AssetCache.Num();
    AssetCache.Empty();
    UE_LOG(LogTemp, Log, TEXT("Cleared %d cached assets"), NumCleared);
}

TArray<FString> UAssetCacheManager::GetCachedAssetPaths()
{
    TArray<FString> Paths;
    AssetCache.GetKeys(Paths);
    return Paths;
}

FString UAssetCacheManager::GetCacheStats()
{
    if (AssetCache.Num() == 0)
    {
        return TEXT("Cache is empty");
    }
    
    int32 TotalOriginalSize = 0;
    int32 TotalCompressedSize = 0;
    int32 CompressedCount = 0;
    
    for (const auto& Entry : AssetCache)
    {
        TotalOriginalSize += Entry.Value.OriginalSize;
        TotalCompressedSize += Entry.Value.CompressedData.Num();
        if (Entry.Value.bIsCompressed)
        {
            CompressedCount++;
        }
    }
    
    float OverallCompressionRatio = TotalOriginalSize > 0 ? 
        (float)TotalCompressedSize / (float)TotalOriginalSize : 1.0f;
    
    return FString::Printf(TEXT("Cache: %d assets, %d compressed, %d -> %d bytes (%.1f%% savings)"),
                          AssetCache.Num(), CompressedCount, TotalOriginalSize, TotalCompressedSize,
                          (1.0f - OverallCompressionRatio) * 100.0f);
}

Utility functions for common operations
namespace ArchiveManagerUtils
{
    // Convert FString to byte array for compression
    TArray<uint8> StringToByteArray(const FString& String)
    {
        TArray<uint8> ByteArray;
        FTCHARToUTF8 Converter(*String);
        ByteArray.Append((uint8*)Converter.Get(), Converter.Length());
        return ByteArray;
    }
    
    // Convert byte array back to FString after decompression
    FString ByteArrayToString(const TArray<uint8>& ByteArray)
    {
        FUTF8ToTCHAR Converter((ANSICHAR*)ByteArray.GetData(), ByteArray.Num());
        return FString(Converter.Length(), Converter.Get());
    }
    
    // Test compression on a sample to determine if it's worth doing
    bool TestCompressionBenefit(const TArray<uint8>& Data, float MinSavingsPercent = 10.0f)
    {
        if (Data.Num() < 100) return false; // Too small to benefit
        
        TArray<uint8> CompressedData;
        int32 OriginalSize;
        
        bool bSuccess = UArchiveManagerBPLibrary::CompressArray(Data, CompressedData, OriginalSize);
        if (!bSuccess) return false;
        
        float CompressionRatio = (float)CompressedData.Num() / (float)OriginalSize;
        float SavingsPercent = (1.0f - CompressionRatio) * 100.0f;
        
        return SavingsPercent >= MinSavingsPercent;
    }
    
    // Compress string data
    bool CompressString(const FString& InputString, TArray<uint8>& OutCompressedData, int32& OutOriginalSize)
    {
        TArray<uint8> StringData = StringToByteArray(InputString);
        return UArchiveManagerBPLibrary::CompressArray(StringData, OutCompressedData, OutOriginalSize);
    }
    
    // Decompress back to string
    bool DecompressString(const TArray<uint8>& CompressedData, int32 OriginalSize, FString& OutString)
    {
        TArray<uint8> DecompressedData;
        bool bSuccess = UArchiveManagerBPLibrary::DecompressArray(CompressedData, OriginalSize, DecompressedData);
        
        if (bSuccess)
        {
            OutString = ByteArrayToString(DecompressedData);
        }
        
        return bSuccess;
    }
}

Error handling and validation
void ErrorHandlingExample()
{
    UE_LOG(LogTemp, Warning, TEXT("=== Testing Error Handling ==="));
    
    // Test 1: Empty array compression
    {
        TArray<uint8> EmptyData;
        TArray<uint8> CompressedData;
        int32 OriginalSize;
        
        bool bResult = UArchiveManagerBPLibrary::CompressArray(EmptyData, CompressedData, OriginalSize);
        UE_LOG(LogTemp, Log, TEXT("Empty array compression: %s (OriginalSize: %d)"), 
               bResult ? TEXT("SUCCESS") : TEXT("FAILED"), OriginalSize);
    }
    
    // Test 2: Invalid decompression with negative size
    {
        TArray<uint8> TestData = {1, 2, 3, 4, 5};
        TArray<uint8> CompressedData;
        int32 ValidOriginalSize;
        
        if (UArchiveManagerBPLibrary::CompressArray(TestData, CompressedData, ValidOriginalSize))
        {
            TArray<uint8> InvalidDecompressed;
            bool bResult = UArchiveManagerBPLibrary::DecompressArray(CompressedData, -1, InvalidDecompressed);
            UE_LOG(LogTemp, Log, TEXT("Negative size decompression: %s"), 
                   bResult ? TEXT("UNEXPECTED SUCCESS") : TEXT("CORRECTLY FAILED"));
        }
    }
    
    // Test 3: Invalid decompression with zero size
    {
        TArray<uint8> TestData = {1, 2, 3, 4, 5};
        TArray<uint8> CompressedData;
        int32 ValidOriginalSize;
        
        if (UArchiveManagerBPLibrary::CompressArray(TestData, CompressedData, ValidOriginalSize))
        {
            TArray<uint8> InvalidDecompressed;
            bool bResult = UArchiveManagerBPLibrary::DecompressArray(CompressedData, 0, InvalidDecompressed);
            UE_LOG(LogTemp, Log, TEXT("Zero size decompression: %s"), 
                   bResult ? TEXT("UNEXPECTED SUCCESS") : TEXT("CORRECTLY FAILED"));
        }
    }
    
    // Test 4: Try to decompress random data
    {
        TArray<uint8> RandomData = {0xFF, 0xAA, 0x55, 0x00, 0x99, 0x77, 0x33, 0x11};
        TArray<uint8> FakeDecompressed;
        bool bResult = UArchiveManagerBPLibrary::DecompressArray(RandomData, 1000, FakeDecompressed);
        UE_LOG(LogTemp, Log, TEXT("Random data decompression: %s"), 
               bResult ? TEXT("UNEXPECTED SUCCESS") : TEXT("CORRECTLY FAILED"));
    }
    
    UE_LOG(LogTemp, Warning, TEXT("=== Error Handling Tests Complete ==="));
}

Advanced Features

Compression Efficiency

The deflate algorithm provides excellent compression for:

  • Text Data: Configuration files, JSON, XML (60-80% compression)
  • Repetitive Data: Level data, tile maps (40-70% compression)
  • Save Game Data: Player progress, inventory (30-60% compression)
  • Network Messages: Large data packets (varies by content type)

Performance Characteristics

  • Fast Compression: Optimized for real-time applications
  • Low Memory Overhead: Minimal temporary memory allocation
  • Predictable Performance: Linear time complexity with data size
  • Thread Safe: Can be used from any thread

Data Type Compatibility

Works with any data that can be represented as byte arrays:

  • Structs: Convert with FMemoryWriter/FMemoryReader
  • Strings: Convert with StringToBytes utilities
  • Images: Raw pixel data compression
  • Audio: PCM audio data compression
  • Custom Data: Any serializable game data

Common Use Cases

Game Development

  • Save Game Compression: Reduce save file sizes by 30-70%
  • Level Data Storage: Compress procedural or user-generated content
  • Asset Caching: Store frequently-used assets in compressed form
  • Network Optimization: Reduce bandwidth usage for large data transfers

Application Development

  • Configuration Data: Compress settings and preference files
  • Document Storage: Reduce storage requirements for text data
  • Cache Management: Store compressed data in memory caches
  • Backup Systems: Compress data before archiving

Best Practices

When to Use Compression

  • Large data sets: Benefits increase with data size (>1KB recommended)
  • Repetitive content: Text, structured data, level data
  • Storage optimization: When disk/memory space is limited
  • Network transmission: When bandwidth is constrained

When to Avoid Compression

  • Already compressed data: Images (JPEG/PNG), audio (MP3/OGG), video
  • Very small data: <100 bytes may not benefit from compression
  • Random data: Truly random data doesn’t compress well
  • Real-time critical paths: When CPU cycles are more valuable than storage

Memory Management

  • Store original size: Always preserve the original size for decompression
  • Validate inputs: Check array sizes before compression/decompression
  • Handle failures: Always check return values for success
  • Consider trade-offs: Balance compression ratio vs. processing time

Error Handling

  • Validate compressed data: Ensure data isn’t corrupted before decompression
  • Size validation: Verify original size parameter is reasonable
  • Fallback strategies: Have plans for when compression/decompression fails
  • Logging: Log compression ratios and failures for debugging

Compression Performance Tips

Optimal Data Preparation

  • Sort similar data: Group similar values together for better compression
  • Remove redundancy: Eliminate duplicate information before compression
  • Use appropriate data types: Smaller data types compress better
  • Batch operations: Compress larger chunks rather than many small pieces

Memory Optimization

  • Reuse arrays: Pre-allocate output arrays when possible
  • Stream large data: For very large datasets, consider chunked processing
  • Monitor memory usage: Track compression overhead in memory-constrained environments

Integration Examples

Blueprint Save System Integration

Custom Event: Save Game
    ↓
Convert Save Data to Bytes
    ↓
Compress array (deflate)
    ↓
Store Compressed Data + Original Size
    ↓
Print String: "Save compressed: X% size reduction"

Network Message Compression

Custom Event: Send Large Message
    ↓
Convert Message to Bytes
    ↓
Branch: Is Data > 500 bytes?
    ↓ (True)
Compress array (deflate)
    ↓
Send Compressed Data + Original Size + Compression Flag
    ↓ (False)
Send Original Data + No Compression Flag

Common Errors

Compression Failures

  • “Compression failed”: Input data may be corrupted or empty
  • Solution: Validate input array has data before compression

Decompression Failures

  • “Decompression failed”: Compressed data is corrupted or original size is wrong
  • Solution: Verify compressed data integrity and correct original size

Size Mismatches

  • “Original size mismatch”: Provided original size doesn’t match actual data
  • Solution: Ensure original size is stored correctly during compression

Memory Issues

  • “Out of memory”: Insufficient memory for decompression buffer
  • Solution: Verify original size is reasonable and memory is available

Table of Contents