Question about DLC

There’s a lot of posts that have been made about this over the years, but most are severely outdated (to a point of irrelevancy) or not really addressing DLC so much as patching.

So I have a game on Steam, and I have DLC pak files containing extra assets. I’d like to allow players the option of downloading these themed paks to their base game, without making it some sort of required patch. The reason for this is because I want the players to have control of the size of the game itself.

I’m not sure how feasible this is and I can’t really find anything addressing how to go about this between UE and Steam. I have found this documentation but it doesn’t really cover how to set this up between UE and Steam and the steps needed to be taken.

Also, in regards to using the pak files.

The big part I’m struggling to figure out is how to upload the pak file to Steam and then have players download it via Steam to their game, and have the game automatically unpack the file. As I understand, I need to have it download directly to the Content/Paks/ folder, and it SHOULD automatically mount on starting up the game itself. But how do I unpack the assets within?

I can currently manually place a pak file in the Content/Paks/ folder and then find it, but I can’t figure out how to unpack it. I’m unfamiliar with how the Asset Registry works and I’ve had a hard time finding understandable and up to date information on it.

Anyway, thank you for reading and any potential insight!

What do you mean by unpacking assets ?

Any pak in the Content/Paks folder is mounted automatically on game startup. That doesn’t mean any asset is loaded, but they are find-able and load-able by the virtual filesystem.
Assets are loaded on-demand, when :

  • specifically loading a path via StaticLoadObject or FSoftObjectPath or FClassFinder
  • opening a level, with a path eg. “/Game/Levels/Level1”
  • as a direct dependency of an asset being loaded

Available assets in pak files are discoverable via asset registry searches.

For example if the intent is to provide DLC maps in paks, you need to set up your UI to do an asset registry search to find all available assets of type “Engine.World” (that’s the class of a level asset), then populate the list dynamically according to the results. Results contain full path to the asset eg. “/Game/Levels/Level1” or “/Game/DLC23/Level23”. Once you run the command open /Game/DLC23/Level23 (or use Travel or whatever), the engine will automatically look up this path within all mounted pak files. Assets used inside the level are loaded similarly, as direct dependencies of the level itself.

Here is a example for searching maps both in blueprints and C++


If you are looking to search for blueprint classes/subclasses, you must use a different method because internally it does not work the same. For that you can use node GetBlueprintAssets which will look specifically for BP subclasses of specified classes, instead of looking for non-code assets.
Here is a BP example of using that, along with how to load the resulting asset into a useable/spawnable class :


Regarding steam, I can’t help much but I believe you can use Steam Workshop to provide optional downloadable content. Players can subscribe to items in the workshop and they get automatically downloaded (and updated), though I’m not sure where they end up on disk. Maybe you can configure a destination path.

Sorry, I had thought you needed to actually unpack the pak file. So if I have a pak file that contains a bunch of mesh, texture, and UAssets, how do I use the registry to get a list of those assets? Assuming I don’t know exactly what objects are in the pak file.

I have found snippets of examples (I’m using c++) of using the registry but I cannot figure out how to specifically code getting/sorting the objects within the pak file. I can find the pak file, but I basically need to get a sorted list of each object within it. My project has a fairly robust map builder and each pak contains a list of themed assets, basically. So players can pick and choose which DLC themes to download and have control over the size of the project as a whole.

The Steam part is certainly weird. I did follow what instructions I found and was able to make a DLC depot, but for the life of me I can’t figure out how to specifically tell it to download the paks to the right directory. Am I correct in understanding that paks should be sent to mygame/Content/Paks?

Thank you for the reply.

Yes paks should be in Content/Paks if you want them to be mounted automatically.

It is also possible to mount them manually, in which case you can specify any path on disk. However it will require C++ to discover them on disk (iterate folders) and mount them.

Regarding iterating pak assets, well I doubt there is a builtin way to do that as you are not really supposed to do it. All mounted paks are kind-of merged into a shared virtual filesystem where everything ends up in /Game/xxx.

Asset registry module is completely independent from file system module so you cannot just ask it to “find assets in pak”.

However there are ways you can organize your stuff to work around this.


For example, if each pak is a theme, you could organize your assets (in editor) such that each theme has its own specific folder, eg:

  • /Content/ClassicTheme/… —> ClassicTheme.pak
  • /Content/SpaceTheme/… —> SpaceTheme.pak
  • /Content/CastleTheme/… —> CastleTheme.pak

Then you can easily use asset registry to iterate assets by path, like this :

auto AssetRegistry = IAssetRegistry::Get();
TArray<FAssetData> Results;
AssetRegistry->GetAssetsByPath("/Game/SpaceTheme", Results, /*recursive*/true);
for (const auto& Data : Results)
{
    // Print in canonical format: " AssetClass'/Path/To/Package.Object' "
    UE_LOG(LogTemp, Log, TEXT("%s'%s.%s'")
        , *Data.AssetClassPath.ToString()
        , *Data.PackageName.ToString()
        , *Data.AssetName.ToString()
    );
}

Alternatively you can use a lower level approach, directly through the Pak system, though it is more complex.

Just like the asset manager has no concept of pak files, the pak system has no concept of assets either, it’s just files. You have to glue the two together yourself. When iterating filesystem (virtual) files, convert paths into asset paths that you can feed into AssetManager, or use as soft object paths for loading, depending on your needs.

Something like this :

auto PPF = (FPakPlatformFile*)FPlatformFileManager::Get().FindPlatformFile(TEXT("PakFile"));

/* get / iterate mounted pak files */
TArray<FString> PakNames;
PPF->GetMountedPakFilenames(PakNames);
for (const FString& PakName : PakNames)
{
    UE_LOG(LogTemp, Log, TEXT("Pak: %s"), *PakName);
}

/* iterate files within a given pak file */
TArray<FString> Files;
PPF->GetPrunedFilenamesInPakFile(PakNames[0], Files);
for (const FString& File : Files)
{
    // File format: "../../../MyProject/Content/SomeBlueprint.uasset"
    UE_LOG(LogTemp, Log, TEXT("File: %s"), *File);

    // Convert to an asset path: "/Game/SomeBlueprint"
    FString AssetPath = FPackageName::FilenameToLongPackageName(File);
    UE_LOG(LogTemp, Log, TEXT("Asset: %s"), *AssetPath);

    // Retrieve corresponding AssetData from AssetManager
    auto Assets = AssetRegistry->GetAssetsByPackageName(*AssetPath);
    // Result is an array, though in most cases there should be only one
    for (FAssetData* Data : Assets)
    {
        UE_LOG(LogTemp, Log, TEXT("%s'%s.%s'")
            , *Data.AssetClassPath.ToString()
            , *Data.PackageName.ToString()
            , *Data.AssetName.ToString()
        );
    } 
}

Oh man, you are awesome! Thank you SO much for taking the time with this, seriously.

My current directory structure does seem to work with what you’re suggesting. For example, I have content/Paks and then a subdirectory for each theme as you described, and am just putting the associated paks in those directories (depending on what DLC the player has downloaded).

My current system basically searches the Paks directory for any .pak files, creating an array of a struct (FString DirectoryName, TArray PakPaths).

So I can get a solid list of each pak based on the theme it’s associated with.

The intention from there is to create instances of of base actor and populate each instance from a list of mesh within the pak file.

So if I have Fortress.pak, perhaps there’s a Tower, Gate, and Wall mesh asset. I’d get all the mesh assets and the selection menu is populated with Tower, Gate and Wall options. Player clicks one of these buttons to place the associated instance (ie spawn BaseActor instance, set mesh to Tower mesh).

I have a plugin I’ve made where I can drag and drop fbx objects into a folder, read their data and create selections to spawn in realtime, so I pretty much have all the core elements needed to do this already. The part throwing me off was that I won’t know what assets are in a pak.

I think your code example will help tremendously so I will give it a shot and report back. <3