# Question about DLC

**URL:** <https://forums.unrealengine.com/t/question-about-dlc/1313648>\
**Category:** C++\
**Tags:** dlc, Steam, unreal-engine, UE5, Packaging, packaging-projects, CPP, question\
**Created:** [September 27, 2023, 3:30am UTC](https://forums.unrealengine.com/t/question-about-dlc/1313648 "2023-09-27T03:30:42Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![RianeN](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@RianeN](https://forums.unrealengine.com/u/RianeN)\
**Post date:** [September 27, 2023, 3:30am UTC](https://forums.unrealengine.com/t/question-about-dlc/1313648/1 "2023-09-27T03:30:42Z")

</div>

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](https://partner.steamgames.com/doc/store/application/dlc) 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!

---

<div class="post-metadata">

**Author:** ![Chatouille](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/chatouille/32/1194622_2.png) [@Chatouille](https://forums.unrealengine.com/u/Chatouille)\
**Post date:** [September 27, 2023, 3:58pm UTC](https://forums.unrealengine.com/t/question-about-dlc/1313648/2 "2023-09-27T15:58:38Z")

</div>

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++

> [@How to check ServerTravel error or check if the map exists](https://forums.unrealengine.com/t/how-to-check-servertravel-error-or-check-if-the-map-exists/823116):
>
> I am using ServerTravel for switching maps in a single player game. ServerTravel returns true even if the map does not exist. The map name will be given by the user and I have to check if it exists first. How can I do that?

* * *

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 :

> [@Get Assets by class always return "Blueprint" classes objects](https://forums.unrealengine.com/t/get-assets-by-class-always-return-blueprint-classes-objects/1256686/2):
>
> Since UE5 the asset registry should be properly able to search for subclasses and provides out-of-the-box functions to do so. Try node GetBlueprintAssets, with an ARFilter set to look for subclasses of your base class Comprobation. The package path depends on where your Comprobation class resides. If it’s a native class, use /Script/ProjectName. If it’s a blueprint class, use package path like /Game/Blueprints/Comprobation and generated class name ie. Comprobation\_C. Once you’ve found some …

* * *

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.

---

<div class="post-metadata">

**Author:** ![RianeN](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@RianeN](https://forums.unrealengine.com/u/RianeN)\
**Post date:** [September 27, 2023, 9:12pm UTC](https://forums.unrealengine.com/t/question-about-dlc/1313648/3 "2023-09-27T21:12:17Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Chatouille](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/chatouille/32/1194622_2.png) [@Chatouille](https://forums.unrealengine.com/u/Chatouille)\
**Post date:** [September 28, 2023, 10:04am UTC](https://forums.unrealengine.com/t/question-about-dlc/1313648/4 "2023-09-28T10:04:15Z")

</div>

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 :

```cpp
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 :

```cpp
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()
        );
    } 
}

```

---

<div class="post-metadata">

**Author:** ![RianeN](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@RianeN](https://forums.unrealengine.com/u/RianeN)\
**Post date:** [September 29, 2023, 12:05am UTC](https://forums.unrealengine.com/t/question-about-dlc/1313648/5 "2023-09-29T00:05:59Z")

</div>

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
