HotPatcher project has been open source for over a year, undergoing numerous updates and optimizations. It has increasingly been chosen by developers as a hot update solution for their projects. During this time, many have inquired about common issues related to UE4 hot updates, which I noticed frequently repeated, so I decided to organize these common questions to help newcomers quickly troubleshoot the UE4 hot update solution.
This article will continually update the Q&A content related to UE4 hot updates and HotPatcher. If you have any questions, feel free to comment directly on this article. I will periodically consolidate responses. You can also join my UE4 hot update group to discuss encountered issues (QQ group 958363331).
Questions Related to HotPatcher
- Can it be used in commercial projects?
The open-source license of this software: allows free use of functionality in commercial projects, but does not permit any third party to charge fees in any form based on this plugin, including but not limited to charging for recorded courses, redistributing the plugin and code, etc.
Can C++ be hot updated?
No, it can only be used to update uasset and Non-Asset (lua/db/json, etc.).Does it support hot updating on mobile platforms?
Yes, HotPatcher has no platform restrictions and can package and manage any platform supported by UE.
Note: When using HotPatcher for packaging, avoid a directory containing both uasset and non-asset files, as this will result in un-cooked uasset packaging.
Series of Articles on Hot Updates
The series of articles I wrote on UE4 hot updates can serve as a reference for project practices:
- UE Hot Update: Requirement Analysis and Solution Design
- UE Resource Hot Update Packaging Tool HotPatcher
- UE Hot Update: Automation Process Based on HotPatcher
- 2020 Unreal Open Day
- UE Hot Update: Splitting the Base Package
- UE Hot Update: Asset Management and Audit Tool
- UE Hot Update: Create Shader Patch
- UE Hot Update: Questions & Answers
- UE Hot Update: Binary Patch Scheme for Resources
- UE Hot Update: Shader Update Strategy
Automatic Mounting Directory for Pak
Pak files in the following three paths will be automatically mounted when the engine starts:
- Engine/Content/Paks
- GAME_DIR/Content/Paks
- GAME_DIR/Saved/Paks
1 | Runtime\PakFile\Private\IPlatformFilePak.cpp |
The default priority of the pak files in these three paths varies (unless named in the form _1_P.pak):
1 | Runtime\PakFile\Private\IPlatformFilePak.cpp |
Purpose of Mount Point
When mounting a Pak, there is a parameter that can specify the MountPoint:
1 | /** |
So, what does it do?
Starting from the Mount function:
1 | if (InPath != NULL) |
If InPath
is passed during the call to Mount, it sets InPath
for the Pak’s FPakFile instance using SetMountPoint
. Actually, in FPakFile, the MountPath has a default value (read from the Pak file). The constructor of FPakFile calls Initialize(Reader, bLoadIndex);
, and in Initialize
, it calls LoadIndex
, where the logic for reading the Pak’s Mount Point from the Pak is implemented:
1 | // Runtime/PakFile/Private/IPlatformFilePak.cpp |
In simple terms, if the Mount Point is not passed during mounting, it will be read from the Pak file. If passed, it will set it to the provided value (the MountPoint in the Pak represents the common path for all files in the Pak).
So, what is the purpose of setting the MountPoint for the Pak?
The real purpose is to check whether the file to be loaded exists in the current Pak! Since the default meaning of the Pak’s Mount Point is the common path of all files within it, all we need to do is check if the file to be read starts with this path, allowing us to eliminate paths that are incorrect (if the base path is wrong, it means the file does not exist in the Pak as well).
The specific logic can be seen in the implementation of this function:
1 | // Runtime/PakFile/Public/IPlatformFilePak.h |
When we read a file from a Pak, it calls the Find
function across all mounted Paks, and the FPakFile::Find
function implements the logic I just described:
1 | // Runtime/PakFile/Private/IPlatformFilePak.cpp |
Therefore, the role of the MountPoint is to first determine if the file’s path matches the foundational path of all files in the Pak during file lookup. If it doesn’t exist, the process will not proceed further.
Pak Fails to Mount
In the main package, if signature is enabled, the resulting Pak will fail to mount.
The same signature error occurs due to the absence of the corresponding .sig file for the pak.
The log looks like this:
1 | LogPakFile: Warning: Couldn't find pak signature file '../../../Pak/Content/Paks/1.0.3_WindowsNoEditor_P.pak' |
This occurs because bEnablePakSigning
in Project Setting
- Crypto
was set to true when creating the primary package, which will enforce validation on all pak
files within the created package to ensure that only pak files packaged by oneself can be loaded.
The related code handling is in:
1 | // Runtime/PakFile/Private/SignedArchiveReader.cpp |
Therefore, if the pak created using HotPatcher does not specify the same encryption parameters as the project, the pak placed within the package will fail to load (due to validation failure).
The solution is to specify the same encryption information in HotPatcher as in the project. When directly using UE to create the primary package, a Crypto.json
file will be generated by default in the following path:
1 | PROJECT_DIRECTORY\Saved\Cooked\WindowsNoEditor\PROJECT_NAME\Metadata\Crypto.json |
Its content is generated based on the options in Project Setting
- Crypto
.
The method to use is:
Add the parameter -cryptokeys="Crypto.json"
to the UnrealPak
parameters in HotPatcher (in UE4.23+ also add the -sign
parameter):
Regenerating the Pak will create a corresponding .sig
file named after the Pak in the Pak directory, and copying both the pak
and sig
files to the mounting directory will work.
The UnrealPak parameters can be found in my previous article: UE4 Toolchain Configuration and Development Tips # Parameters of UnrealPak
Pak master signature table check failed for pak
- The pak generated by HotPatcher crashes when mounted, with the message Pak master signature table check failed for pak.
This is due to the signing encryption set in the project settings when creating the primary package, and identical encryption parameters must be added in the UnrealPak parameters of HotPatcher.
In IPlatformFilePak.cpp
within RegisterPakFile
, checks are also performed:
1 | // Runtime/PakFile/Private/ |
iOS Hot Update metallib Issue
In 4.25, there is an issue where shader bytecode is not reloaded. The engine internally handles the loading of metallib in a separate process and cannot reuse the shader bytecode process. Consequently, for iOS packages, it is advisable to use remote packaging, which will generate ushaderbytecode
. In 4.25 the LoadLibrary doesn’t show issues, but loading metallib does.
You can refer to my previous article on UE hot update regarding shaders: UE Hot Update: Create Shader Patch
UE4.25+ ShaderPatch Crash
This issue arises due to a bug in the engine 4.25+, and you can find a modification plan in this article: UE Hot Update: Create Shader Patch#4.25+ ShaderPatch Crash.
Hot Updating Resources Not Present in a Plugin
After packaging, the engine will read the current project’s plugin names from the upluginmanifest. When loading resources from plugins, it checks for the existence of the plugin to achieve a coarse filtering effect.
Thus, if trying to package a plugin that doesn’t exist in the base package into the pak, you must synchronize the project’s upluginmanifest
file during resource packaging, mounted at:
1 | ../../../PROJECT_NAME/Plugins/PROJECT_NAME.upluginmanifest |
For more information on upluginmanifest
, you can refer to my previous notes: UE4#upluginmanifest.
Hot Update Resources Not Taking Effect
If the hot updated Blueprints logic remains unchanged, check whether the resources have been cooked. You can manually execute cooking on selected resources via the features provided in HotPatcher in the Content Browser. Alternatively, ensure the bCookAsset
option is checked when packaging the patch.
Hot Update Material Loss
If new resources/materials have been hot updated and they have no effect, check whether shader bytecode has been packaged. Failing to package shader bytecode for newly added materials will result in the engine using the default material due to shader retrieval failures.
The log error would be:
If you used bSharedShaderLibrary
during packaging, you must manually reload the shader bytecode after mounting pak files that contain new shader bytecode, allowing the engine to retrieve the latest Shader when loading materials:
1 |
|
You should call this according to the actual path and naming of the ShaderLib after mounting.
If bSharedShaderLibrary
was not enabled, no further action is required, as the engine will default to using the inline shader code within the resource.
Is Hot Updating AssetRegistry Necessary?
It depends on your needs. If the code at runtime references resource relationships or checks for resource existence using the AssetRegistry module, then it needs to be hot updated. However, the AssetRegistry is not essential for the engine, and if you’re sure it won’t be used at runtime, you can remove it, which will save some memory.
For more specific information, you can refer to my previous notes: UE4#Control AssetRegistry Serialization.
Android Prompts Not Found uproject
There’s a bug in UE that can be reproduced in version 4.25.1 with the following steps:
- Install the apk and launch the game for the first time.
- Open UE’s sandbox data directory
UE4Game/PROJECTNAME
and create aContent/Paks
directory in this location. - Restart the game.
The log also mentions Project file not found: ../../../FGame/FGame.uproject
.
Pak files that automatically mount on Android can be placed in the Saved/Paks
directory. I will analyze this issue in detail when I have time.
Control Resources Not Packed in Base Package
Practices on splitting base packages can be found in my two articles:
Analyze Resources in the Package of a Specific Platform
You can use the Asset Audit tool provided by UE. Be sure to back up the DevelopmentAssetRegistry.bin file in the Cooked/PLATFORM/PROJECT_NAME/Metadata directory each time packaging.
Alternatively, you can use UnrealPakViewer to directly load Pak files.
You can refer to the asset audit section in this article: UE Hot Update: Asset Management and Audit Tool#Asset Audit.
UMG Child Widgets Hot Update Not Effective
If UMG is referenced in an instanced form, changes to child UMG must recursively include all UMG resources referenced in the form of child controls. I previously recorded this issue in my notes: UE4#UMG Child Widget Reference Hot Update Issue.
Solution: HotPatcher includes an option to recursively analyze the UMG parent widget (bRecursiveWidgetTree), which can be enabled.
A detailed analysis of this issue was presented in my 2020 UOD speech, and you can watch the video and view the PPT here:
Note: Instanced UMG only affects the serialization of controls and does not relate to logical changes within child widgets.
In the following scenario, only packaging a child widget UMG will be effective:
- UMG_Child has a Button associated with a Button event that outputs TEST01.
- UMG_Main embeds UMG_Child.
- A version is built.
- Modify the output of the Button event in UMG_Child to TEST02.
- Only package
UMG_Child
. - Create UMG_Main and click the Button in its UMG_Child to correctly output TEST02.
Can Pak be Used Across Engine Versions?
No, the engine versions for packaging and usage must be consistent.
Pak Packaged from Project A for Use in Project B
HotPatcher has implemented a functionality to replace the pak command, which can be specified with the following parameters:
Note: Both From and To must include a ../../../
prefix; otherwise, the absolute path of the file will be replaced.
Plugin HotPatcher Failed
After packaging, the following prompt appears:
This may be caused by packaging a purely Blueprint project. Create a C++ class in the project, transforming it into a C++ project and repackage it.
Packaging Original uasset Resources
Currently, there is no direct feature in the plugin to select original uasset resources for packaging, but you can implement it using a clever workaround.
You can set ReplacePakCommandTexts
to replace the Cooked directory with the project’s Content directory
:
Although the *pakcommand.txt
will still contain records of uexp
files, they won’t be available in the project’s Content
, meaning they won’t be packed into the pak, skipping nonexistent files and producing the following log output:
1 | LogPakFile: Warning: Missing file "D:/Client/Content/Assets/Scene/Map/LookDev/DemoAssets/Mesh/FFXV/000.uexp" will not be added to PAK file. |
This is a clever approach, but it works.
Export Cross-Machine Universal Configuration File
Q: Some configurations exported from HotPatcher depend on absolute file paths, such as BaseVersion, Non-Asset files, SavePath, etc. These absolute paths may not be consistent across different machines. Can configurations be based on relative paths?
A: Yes. All configurable items in HotPatcher can replace absolute paths with marked symbols, and the following symbols can be used to replace absolute paths.
1 | [ENGINEDIR] |
During packaging, these will automatically be replaced with the absolute path of the current machine, making the configuration file fully universal.
Analysis of Dependency Time Consumption
When a project has a considerable amount of resources, the dependency analysis provided by the plugin can consume substantial time. Its primary purpose is to analyze dependent resources to prevent dependency on resources that haven’t been packaged.
If dependencies on engine or plugin resources exist, not conducting dependency analysis will result in mismanagement (or manually specifying), and if you wish to exclude unreferenced resources, it cannot be accomplished without analysis. If not needed, you can disable it by setting bAnalysisFilterDependencies
.
This will limit the analysis to only the resources specified in the configuration and those individually designated, comparing them with the base version. This can significantly reduce the time consumed in dependency analysis (if your resources are numerously substantial and sure all resource dependencies reside in /Game, you can skip enabling dependency analysis).
Memory Mapped File Has the Wrong Alignment
Note: The latest plugin has already been adapted to be supported, and no manual specifications are required.
The following crash occurs in the iOS package:
1 | IsAligned(MappedRegion->GetMappedPtr(), FPlatformProperties::GetMemoryMappingAlignment()), TEXT("Memory mapped file has the wrong alignment!") |
This is caused because the alignformemorymapping
value was not set when packaging for iOS, which defaults to 0. However, for iOS, it should be set to 16384
:
1 | Engine/Source/Runtime/Core/Public/IOS/IOSPlatformProperties.h |
Specify this parameter during pak packaging: -alignformemorymapping=16384
.
During default UE packaging, this parameter has also been added:
1 | Source\Programs\AutomationTool\Scripts\CopyBuildToStagingDirectory.Automation.cs |
It reads from the MemoryMappedFiles
Section of Config/PLATFORM/*Engine.ini
, where the Alignment
value is specified, such as for iOS:
1 | Config/IOS/IOSEngine.ini |
This value corresponds to the one defined in the code and is the only platform for iOS that specifies this item: MemoryMappedFiles.
Missing Some Plugin Resources in Release
Please ensure that the plugin path name matches exactly with the plugin name. For example:
1 | Plugins\HDiffPatchUE4\HDiffPatch.uplugin |
This situation is not allowed; the path must match the plugin name exactly.
Resource Packaging and Real Machine Load Process in the Editor
As in-game resources increase in number, the package size grows, but mobile package sizes have limits and cannot indefinitely include all resources in the base package. The Android limit is 2G (you can enable Allow Large Obb files
to support 4G), and the iOS limit for submission to the App Store is usually 4G, which typically maintains uniform resource allocation across iOS/Android basic packages, with the remaining resources updated to devices through hot updates or dynamic downloads.
So, effectively in the development phase, resources packed in the basic package are merely a part of the project. Often, satisfying the verification needs of planners, artists, and testers can prove difficult.
- New maps and resources need to be viewed on actual devices
- Issues with resources in the package; submission waits for lengthy full package build periods
- Base package resource volumes exceed limits, which may prevent additional resource additions
Based on this necessity, a basic package + patch form can be utilized during the development phase.
Resource Packaging
In our current project, within the editor, you can right-click directly on the resource or directory and select Cook And Pak Actions, choose the corresponding platform, and also select AnalysisDependencies (Analyze Dependencies).
Different platforms require different choices (select based on your project’s needs):
- Android: Android_ASTC
- iOS: iOS
- PCVersion: WindowsNoEditor
After execution, a prompt will appear at the bottom right:
You need to wait until the execution is complete. This process will not freeze the editor; other editing operations can continue.
The duration of execution depends on the number of referenced resources and whether the selected resources have been packaged previously (Data Driven Content).
After execution, a corresponding .pak file will be created in the project’s Saved/HotPatcher/Paks/{EXECUTE_TIME}/Android_ASTC
directory. This pak file is the patch for the packaged resources, with the file name including the platform name. The pak files for different platforms cannot be mixed.
Placement in Real Machines
PCVersion
For PCVersion, place the pak file in the following directory:
1 | WindowsNoEditor\PROJECT_NAME\Content\Paks |
If the Paks directory doesn’t exist, you may manually create it.
Android
On Android, the pak file needs to be placed in the following directory:
1 | UE4Game/PROJECT_NAME/PROJECT_NAME/Saved/Paks |
If the data directory has been modified to the sandbox path, it will be:
1 | Android/data/com.xxxx.yyyy/files/UE4Game/PROJECT_NAME/PROJECT_NAME/Saved/Paks |
If the Paks directory doesn’t exist, you may manually create one.
iOS
The iOS process is more intricate; you need to use tools like iCareFone or iMazing to transfer the files. Place it in Documents - PROJECT_NAME - Saved - Paks. If the Paks directory doesn’t exist, you may manually create it.
Check Mounting Status
After placing the pak file in the above directory, you can start the game.
To confirm whether the pak file is effective, you can check the Log:
1 | LogPakFile: Display: Found Pak file ../../../PROJECT_NAME/Saved/Paks/2022.10.18-13.02.53_IOS_001_P.pak attempting to mount. |
If you see such Log, it means the resource package has been successfully read by the engine and can be used directly, just like it was included in the base package.### Notes
The priority of manually packing the Pak is higher than that of the resources in the base package, which means if a resource exists in both the patch package and the base package, it will replace the one in the base package, similar to hot update logic.
- Different platform pak files cannot be mixed!
- After testing, you need to delete the pak files from the device; otherwise, newly created packages may have resource display errors.
Troubleshooting UE5+
Note: Starting from v82.0, it is compatible with UE5.2 and 5.3.
If you find that the packaged Pak has issues in UE5:
- Pak cannot mount: Check if the project has IoStore enabled. After disabling it in project settings, repackage the base package.