Overview
PackCraft packs and unpacks archives while your game or tool is running: export and import save games, mods, user content, logs or downloaded data packs. Pick an archiver class, then create or open an archive in a file or in memory, add entries from files or byte arrays, list them and extract them. One-node async actions archive or extract whole directories with progress reporting.
- Zip (Zip64 for archives written to disk), Tar, Tar + GZip, Tar + LZ4 and Tar + Oodle (UE 5) archivers sharing one set of nodes.
- Archives in files or entirely in memory; append entries to existing zip files.
- Async Archive Directory / Archive Files / Unarchive Directory / Unarchive Files nodes with success, progress and failure pins.
- Entry listing by index or name with sizes, directory flag and creation time.
- Compression levels 0–10 per entry.
- Raw GZip, LZ4 and Oodle buffer compression on a background thread.
- Central error event on an engine subsystem plus a dedicated log category.
Requirements
| Requirement | Details |
| Unreal Engine | 4.27 and 5.8 (verified clean on both) |
| Modules | PackCraft (Runtime) |
| Dependencies | None |
| Language | Blueprints and C++ |
| Platforms | No platform restriction in the plugin descriptor. Win64 is verified by Alpha XP; other platforms are supported by the code, not verified by Alpha XP. Oodle formats require UE 5. |
Installation
- Close the editor and copy the
PackCraft folder into your project's Plugins/ folder (create it if needed), or install the plugin from Fab into your engine.
- Open the project. For a C++ project, let the editor rebuild the plugin module when prompted, or build the project from your IDE.
- Enable PackCraft in Edit > Plugins (search for “PackCraft”) and restart the editor.
- C++ only: add
"PackCraft" to PublicDependencyModuleNames in your module's .Build.cs.
Verifying the install In a Blueprint graph, search for Archive Directory under PackCraft|Async.
Quick start
Blueprint — one node
- Add Archive Directory (category PackCraft|Async).
- Set Archiver Class to Pack Craft Zip, Archive Path to the zip to create, Directory Path to the folder to pack.
- Handle the On Success, On Progress and On Fail pins.
- Use Unarchive Directory or Unarchive Files to extract again.
Blueprint — step by step
- Create Archiver with the archiver class you need, and keep the result in a variable.
- Create Archive in Storage (or Create Archive in Memory / Open Archive from Storage).
- Add Entry from Storage for each file, or Add Entry from Memory for a byte array.
- Close Archive to write the archive.
C++
#include "PackCraftBase.h"
#include "ArchiverZip/PackCraftZip.h"
#include "Misc/Paths.h"
void UMySaveExporter::ExportSlot()
{
const FString ArchivePath = FPaths::ProjectSavedDir() / TEXT("Backup.zip");
UPackCraftBase* Writer = UPackCraftBase::CreateArchiver(this, UPackCraftZip::StaticClass());
if (Writer->CreateArchiveInStorage(ArchivePath))
{
Writer->AddEntryFromStorage(TEXT("SaveGames/Slot1.sav"), FPaths::ProjectSavedDir() / TEXT("SaveGames/Slot1.sav"));
Writer->CloseArchive();
}
UPackCraftBase* Reader = UPackCraftBase::CreateArchiver(this, UPackCraftZip::StaticClass());
if (Reader->OpenArchiveFromStorage(ArchivePath))
{
FPackCraftEntry Entry;
TArray64<uint8> Data;
if (Reader->GetArchiveEntryInfoByName(TEXT("SaveGames/Slot1.sav"), Entry) && Reader->ExtractEntryToMemory(Entry, Data))
{
UE_LOG(LogTemp, Log, TEXT("Extracted %lld bytes"), Data.Num());
}
Reader->CloseArchive();
}
}
Archiver classes
| Class | Type | Description |
| UPackCraftZip | Class | Zip archives (Zip64 when written to disk); also opens an existing zip to append entries. |
| UPackCraftTar | Class | Tar archives. |
| UPackCraftGZip | Class | Tar archives compressed with GZip (.tar.gz / .tgz). |
| UPackCraftLZ4 | Class | Tar archives compressed with LZ4. |
| UPackCraftOodle | Class | Tar archives compressed with Oodle (UE 5 only). |
| UPackCraftBase | Class | Abstract base of the archiver classes; all archive nodes are defined here. |
| UPackCraftRaw | Class | Raw buffer compression and decompression (GZip, LZ4, Oodle on UE 5). |
| UPackCraftSubsystem | Class | Engine subsystem that broadcasts every archiver error. |
| UPackCraftUtilities | Class | Utility functions. |
| UPackCraftArchiveAsyncTask / UPackCraftUnarchiveAsyncTask | Class | Async Blueprint actions behind the Archive / Unarchive nodes. |
Async archive nodes
Latent nodes in PackCraft|Async. Each takes an Archiver Class and keeps its archiver alive until it finishes.
| Node | Type | Description |
| Archive Directory | Async | Creates an archive file of the chosen archiver class from a directory (optionally including the directory itself as the parent entry). |
| Archive Files | Async | Creates an archive file from a list of file paths. |
| Unarchive Directory | Async | Opens an archive file and extracts one directory entry (or every entry when Entry Name is empty) into a directory. |
| Unarchive Files | Async | Opens an archive file and extracts the named entries into a directory. |
| On Success | Event | Output pin: the operation finished (Percentage 100). |
| On Progress | Event | Output pin: progress in percent while files are added or extracted. |
| On Fail | Event | Output pin: the operation failed; details go to the log and the subsystem's On Error event. |
Archive nodes
Callable on an archiver created with Create Archiver (categories PackCraft|Create, Open, Close, Get, Add, Extract). Most return a success flag. Asynchronous variants run on a background thread and call their delegates on the game thread.
| Node | Type | Description |
| Create Archiver | Callable | Creates an archiver of the chosen class (Zip, Tar, GZip, LZ4, Oodle); the output is typed to that class. |
| Create Archive in Storage | Callable | Starts a new archive at a file path. The file is written when the archive is closed. |
| Create Archive in Memory | Callable | Starts a new archive in memory with an optional initial allocation size. |
| Open Archive from Storage | Callable | Opens an existing archive file for reading. |
| Open Archive from Memory | Callable | Opens an archive from a byte array for reading. |
| Open Archive from Storage to Append | Callable | Zip archiver only: opens an existing zip file to add more entries. |
| Close Archive | Callable | Finalises and closes the archive (writes the file for archives created in storage). |
| Get Archive Data | Callable | Returns the bytes of an archive created in memory. |
| Get Archive Entries | Callable | Returns the number of entries. |
| Get Archive Entry Info by Name | Callable | Finds an entry by its name and returns its information. |
| Get Archive Entry Info by Index | Callable | Returns the information of the entry at an index. |
| Add Entry from Storage | Callable | Adds a file from disk under an entry name, with a compression level. |
| Add Entries from Storage | Callable | Adds a list of files asynchronously with result and progress delegates. |
| Add Entries from Storage Directory | Callable | Adds a whole directory recursively and asynchronously, optionally keeping the directory as the parent entry. |
| Add Entry from Memory | Callable | Adds an entry from a byte array. |
| Extract Entry to Storage | Callable | Extracts one entry (file or directory) to a path, optionally overwriting. |
| Extract Entries to Storage | Callable | Extracts a list of entries into a directory asynchronously with result and progress delegates. |
| Extract Entries to Storage Directory | Callable | Extracts a directory entry (or everything) into a directory asynchronously. |
| Extract Entry to Memory | Callable | Extracts a file entry into a byte array. |
Raw compression, utilities and errors
| Node | Type | Description |
| Compress Raw Data Async | Callable | Compresses a byte array with GZip, LZ4 or Oodle on a background thread; the result delegate runs on the game thread. |
| Uncompress Raw Data Async | Callable | Decompresses a byte array produced by the same format on a background thread. |
| Parse Directories | Callable | Returns every parent directory of a path (“A/B/File.txt” gives “A/” and “A/B/”). |
| On Error | Event | PackCraft Subsystem event broadcast with an error code and message whenever an archiver reports an error. |
Types
| Type | Kind | Description |
| FPackCraftEntry | Struct | Entry information: Index, Name, bIsDirectory, UncompressedSize, CompressedSize, CreationTime. Obtain it from the Get Archive Entry Info nodes; do not fill it manually. |
| EPackCraftCompressionLevel | Enum | 0 (no compression) to 10 (best compression); default 6. |
| EPackCraftRawFormat | Enum | Oodle, GZip, LZ4. |
| EPackCraftErrorCode | Enum | Not Initialized, Unsupported Mode, Unsupported Location, Extract Error, Add Error, Close Error, Get Error, Invalid Argument. |
Troubleshooting
| Symptom | Cause and fix |
| Oodle archives or raw Oodle compression fail on UE 4.27 | Oodle is available on UE 5 only; on 4.27 the log reports that the Oodle format is not supported. Use Zip, GZip or LZ4 there. |
| The archive file is never written | Archives created in storage are finalised and written by Close Archive. Call it when you have added every entry (the async archive nodes do this for you). |
| “Only 'Write' mode is supported for adding entries” | The archive was opened for reading. Create a new archive, or use Open Archive from Storage to Append on a Zip archiver. |
| “It is impossible to extract directory entry into memory” | Directory entries have no data. Extract them with Extract Entry to Storage, or skip entries whose bIsDirectory is set. |
| “Array with int32 size … cannot fit int64 size data” | Blueprint byte arrays hold at most 2 GB. Use the C++ TArray64 overloads for larger data. |
| No more entries can be added after Get Archive Data on a Zip | Getting the data of an in-memory zip finalises it. Add every entry first, then call Get Archive Data. |
| Where do errors go? | Every error is logged to LogPackCraft and broadcast by the On Error event of the PackCraft Subsystem (an engine subsystem). |