The EULA License Grant/(A) of UE clearly states that content developed using UE and redistributed must not include uncooked source formats or paid content developed based on engine tools. This article studies the specific content distribution details in the EULA and how to technically circumvent this limitation.
There is no restriction on your Distribution of a Product made using the Licensed Technology that does not include any Engine Code or any Paid Content Distributed in uncooked source format (in each case, including as modified by you under the License) and does not require any Licensed Technology (including as modified by you under the License) to run (“Unrestricted Products”). For clarity, the foregoing does not constitute a license under any patents, copyrights, trademarks, trade secrets or other intellectual property rights, whether by implication, estoppel or otherwise.
The definition of Engine Tools
in the EULA is:
“Engine Tools” means (a) editors and other tools included in the Engine Code; (b) any code and modules in either the Developer or Editor folders, including in object code format, whether statically or dynamically linked; and (c) other software that may be used to develop standalone products based on the Licensed Technology.
This means developers cannot use any modules under Editor
or Developer
in game content.
The user agreement is a legally binding document. I intend to tinker a bit and also take a look at how UE implements this limitation, solely for the purpose of record analysis, and will not engage in commercial redistribution or use it in formal projects. I read through the logic in UBT, and the code only needs a few simple modifications.
Note: Doing this in a formal release version violates the UE’s EULA, and it is strongly discouraged in official projects.
The code and compilation in this article are based on UE_4.18 (engine compiled from source locally), and the operations described in this article do not apply to engines installed from EpicLauncher, the reasons will be noted at the end.
In UE, when the packaged game (Target is Game
) is Shipping
, if the project contains Editor
/Developer
modules, the following error will be reported:
1 | UATHelper: Packaging (Windows (64-bit)): ERROR: ERROR: Non-editor build cannot depend on non-redistributable modules. C:\Users\imzlp\Documents\Unreal Projects\EULA418\Binaries\Win64\EULA418-Win64-Shipping.exe depends on 'DesktopPlatform'. |
This means the DesktopPlatform
is a non-redistributable module, and cannot be used in Game
. By reviewing the UBT code, this exception is thrown in UBT’s CheckForEULAViolation
:
1 | // Source/Programs/UnrealBuildTools/Configuration/UEBuildTarget.cs |
The key judgment is the IsRedistributable
method (conceptually similar to a member function in C++):
1 | // Source/Programs/UnrealBuildTools/Configuration/UEBuildTarget.cs |
The judgment here is whether the module belongs to Editor
/Developer
; if so, it returns true
, leading to the exception being thrown later. For testing, I directly modified it to return true;
.
However, even after making just that change, the packaging still fails, but now the error changes to a linking error. Continuing to look at the UBT code, I find another place that makes a check for the Shipping
mode (the // ...
indicates omitted unrelated code):
1 | // Source/Programs/UnrealBuildTools/Configuration/UEBuildTarget.cs |
Comment out the above part regarding bAllowDeveloperModules
, then change it to:
1 | Directories.Add(UnrealBuildTool.EngineSourceDeveloperDirectory); |
Recompiling UBT is sufficient.
Now I can write a simple example to test, such as using the DesktopPlatform
from Developer to call the system’s file selection.
First, add the DesktopPlatform
module dependency in *.build.cs
:
1 | PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" ,"DesktopPlatform"}); |
Then write a simple function exposed to Blueprints:
1 | // .h |
Under normal circumstances, packaging the above code as Shipping will produce the initial error mentioned in the article, but after our modifications, it can package successfully and execute correctly. This simple project and its packaged content can be downloaded here.
After launching, press the number key 1
(not Num 1
) to open the Windows file selection window, and after selecting, the path of the chosen file will be displayed on the screen.
Note: You need to use the source version of the engine to compile the project. If you encounter a
noexcept
compilation error, you can addbForceEnableExceptions = true;
in the project’s*.target.cs
.
Recompiling the project will compile the modules in the engine (opening the folder of the engine installed from EpicLauncher will show that the default Editor/Developer modules have not compiled static libraries, which is why you cannot execute the operations described in this article using the engine installed from EpicLauncher).