Trying to build a standalone MOD/DLC pak file
Here is my loooong question post.
I spend a good amount of time and finally could successfully confirmed that Tom Looman's MOD example works as described with 4.19.2 on Windows 10 64 bit. (I created my own project with 4.19.2 rather than converting his project. So the filenames are slightly different from his)
The trick I found is that his tutorial enables the MOD plugin both when I cook the executable and when I cook the MOD plugin. With this process, I confirmed that NewMapMod.uplugin file is cooked in executable's pak file and the rest of Plugin contents are cooked in plugin's pak file. (I used "UnrealPak.exe [pakfilename] -List" command to confirm that) And after I put the plugin .pak file next to the executable's .pak file, I could run the game and load the DLC map. Nice.
Then I looked for if there is a way to include NewMapMod.uplugin in the plugin's pak file and make the MOD plugin independent from specific executable build. According to engine source, it seems the key is "DLCPakPluginFile" option for the cooker. So I tried to use the option and failed. I like to know how to use the option correctly.
Let me explain my failed attempt in detail below.
First, I disabled the MOD plugin when I cooked the executable then enabled the MOD plugin when I cooked the plugin and check which file is in each pak. In this way, NewMapMod.uplugin isn't in the executable anymore as expected. But NewMapMod.uplugin is not in plugin pak file either. Loading NewMap.umap from with "open NewMap" command in the game fails. (I guess it's because UE doesn't recognize the plugin due to lack of .uplugin file. This implies MOD plugin must be recognized as a valid plugin on Windows)
Then, I looked for the reason why NewMapMod.uplugin isn't in the plugin's .pak file. And I found the line 283 of https://github.com/EpicGames/UnrealEngine/blob/8e4560b8c22b309e73ff0ce90377742c3dfe13cc/Engine/Source/Programs/AutomationTool/Scripts/CopyBuildToStagingDirectory.Automation.cs excludes any .uplugin file from the .pak file by default.
And I learned that I can add "-DLCPakPluginFile" as Additional Cooker Options from Project Launcher to forcefully include .uplugin file to the plugin pak. (See https://github.com/EpicGames/UnrealEngine/blob/8e4560b8c22b309e73ff0ce90377742c3dfe13cc/Engine/Source/Programs/AutomationTool/AutomationUtils/ProjectParams.cs) I also add "-CookAll" option just in case.
After cooking the executable and the plugin with those options, I confirmed NewMapMod.uplugin is in the plugin .pak file. So I thought I should be able to load the DLC map finally. But I have no luck... Putting the plugin .pak file next to the executable .pak, then running "open NewMap" command in the game doesn't load the map. I hope someone can give me some advice.
(Especially I want to know to what extent did I come. Is the pak file properly mounted? Is it working as a plugin already? If so, why loading map fails? How can I effectively debug this .pak loading process?)
The project file I used is here. I included the Launcher profile in the UnrealFrontend directory. I also included Pak file comparison with each different build method in PakFileExaminationResult. https://drive.google.com/file/d/15zFW6IA4bJTRw9Ph0brlG_g2ySfGjo5t/view?usp=sharing
Hi! I'm using UE 4.20, but I was having the same problem as you: "how to load DLC pak when base game doesn't know about its plugin?"
After fiddling for days on the engine source, here are my findings (and I made it work \o/).
The uplugin file doesn't work after base game is built
There's a part of the engine called PluginManager that creates the plugin content root when the game starts. For it to happen, the plugin must be part of the game. So, if you build the game without the plugin and load a pak file made with that plugin (let's call it DLCPlugin), Unreal won't create the /DLCPlugin/ content root and, even though you mounted the DLCPlugin pak, the engine has no idea of how to find its files. They are on there on the drive, but their path is unknown to the engine PackageName class, that takes care of converting logical paths to files on the hard drive. This will happen even if you let the engine mount the pak by having it on the right folder at startup. It mounts the pak, but doesn't add its root content path to the engine, because that's the PluginManager's job. And it doesn't mater if you add the plugin file to the pak. The PluginManager doesn't seem to search for plugins on mounted paks.
Making Unreal find the DLC plugin pak contents
After your mount pak code or, if you are letting the engine load the pak by itself, on some BeginPlay event (to do it as soon as possible), you need to register the DLC root path together with its content path.
The root path is the logical path, stored on PackageName. It'll be /DLCPluginName/. Just like /Game/, /Engine/ etc. These are logical paths that Unreal redirects to some path on the hard drive.
The content path is the hardware one. It's the one root path will redirect to. So, if you manually mounted the pak in
The function to register the new root is
Keeping DLC content references
After mounting the pak and registering its root, Unreal will see the pak's files as /RootPath/Path/Relative/ToContentPath/File. So, let's say you have a DLC plugin called DLCPlugin with a Maps folder and a DLCMap file and another Meshes folder with a Sphere asset. Then you add that Sphere to your map. The map expects to find the sphere in /DLCPlugin/Meshes/Sphere, because that's the path in the editor. BUT, with Project Launcher built DLC paks there's a catch!
Inside the DLC plugin pak, the path for those two files will be /Content/Maps/DLCMap for the map and /Content/Meshes/Sphere for the sphere. So the reference the map has to the sphere will be broken, because with the root registered like I said before, its path would become /DLCPlugin/Content/Meshes/Sphere.
Now, you can't change the paths of the files inside the mounted pak to fix that. But you can map the root to the Content folder after mounting the pak. After all, its contents are in the hard drive with all its folders in it!
So, in order to keep the same paths as they were in the editor (like /DLCName/Meshes/Sphere), do as below (depending on how you mount the pak). The RootPath will always be /[DLCName]/. The ContentPath is the one that changes.
If you mount the pak using FPakPlatformFile::Mount
You'll have a mount point. Let's call it MountPoint. When you call
If you let the engine mount for you or use FCoreDelegates:OnMount
Or if you're using
Always check if FPaths::ProjectDir() is returning a / at the end to avoid missing it or having it doubled.
I have only tested this information on Windows. So I don't know yet about other systems.
Follow this question
Once you sign in you will be able to subscribe for any updates here