ue-module-build-system

Use when working with Build.cs, Target.cs, module creation, plugin setup, or build errors in Unreal Engine — including "unresolved external symbol," "cannot open include file," IWYU violations, missing API macros, or dependency configuration. See also ue-cpp-foundations for UObject macro patterns.

By quodsoler · 890 installs

npx skills add quodsoler/unreal-engine-skills --skill ue-module-build-system

Source repository · Upstream listing

UE Module & Build System Target engine: UE 5.8 . APIs below are verified against the 5.8 headers and UnrealBuildTool sources; older forms are listed under "Deprecated — do not use". This skill covers UnrealBuildTool (UBT) ModuleRules ( .Build.cs ) and TargetRules ( .Target.cs ), the .uproject and .uplugin descriptors, module registration ( IModuleInterface and IMPLEMENT MODULE in Modules/ModuleManager.h , module Core ), plugin discovery ( IPluginManager in Interfaces/IPluginManager.h , module Projects ), and the compiler, linker, UHT and UBT errors those files cause. Context Read .agents/ue project context.md if it exists (module names, conventions, enabled plugins, GAS/networking setup). Do not stop if it is missing. Identify the area from the request and the codebase. Ask only when two plausible readings would produce different code. Request is about… Go to Dependencies, include paths, PCH, warnings in an existing Build.cs [Build.cs Anatomy]( buildcs anatomy) Target.cs , BuildSettingsVersion , IncludeOrderVersion , target types [Target.cs]( targetcs) .uproject , module Type , LoadingPhase , enabling plugins [.uproject File]( uproject file) Adding a module ( IMPLEMENT MODULE , module interface, StartupModule ) [Creating a New Module]( creating a new module) Adding a plugin ( .uplugin , runtime + editor modules, dependencies) [Creating a Plugin]( creating a plugin) "Which module do I add to use type X?" [Which Module Provides This Type]( which module provides this type) LNK2019, C1083, UHT, UBT or runtime module load errors [Resolving Build Errors]( resolving build errors) Build.cs Anatomy Every module has <ModuleName .Build.cs next to its Public/ and Private/ folders. The class name must equal the module name. Public vs Private Dependencies Field Use when PublicDependencyModuleNames A type from the module appears in one of your Public/ headers (base class, member, parameter, return type, UPROPERTY ). Downstream modules inherit the include paths. PrivateDependencyModuleNames The module is used only in Private/ .cpp files or private headers. PublicIncludePathModuleNames / PrivateIncludePathModuleNames You need the module's headers (forward declarations, inline types) but link nothing from it. DynamicallyLoadedModuleNames You call FModuleManager::Get().LoadModule(...) yourself; UBT only ensures the module is built. Start private and promote to public only when a public header forces it. Everything public inflates compile time for every downstream module. Include Paths and IWYU UBT discovers Public/ , Internal/ and Private/ automatically; PublicIncludePaths / PrivateIncludePaths exist for extra subfolders only. Under BuildSettingsVersion.V2 and later, bLegacyPublicIncludePaths is false, so headers from other modules are written relative to that module's Public/ (or Classes/ ) root: IWYUSupport defaults to IWYUSupport.Full , which lets UnrealBuildTool Mode=IWYU rewrite the module's includes; set IWYUSupport = IWYUSupport.KeepAsIs for code you maintain by hand. API Export Macro UBT defines <MODULENAME API (module name upper cased plus API ) as DLLEXPORT while compiling the module and DLLIMPORT for importers; monolithic builds define it empty. Anything referenced from another module needs it: Engine headers wrap this as define UE API CORE API at the top of a file and undef UE API at the bottom ( Async/Mutex.h ). That is an engine only convention; project code writes MYGAME API directly. Missing MYGAME API on a class another module references is the most common cause of LNK2019. Warnings and Compiler Flags Every ModuleRules field, the RuntimeDependencies API, platform conditionals and the full engine module table are in [references/build cs reference.md](references/build cs reference.md). Target.cs Source/MyGame.Target.cs and Source/MyGameEditor.Target.cs . The class must be named <FileName Target ; UBT otherwise fails with "Expecting to find a type to be declared in a target rules named 'MyGameTarget'". Source/MyGameEditor.Target.cs declares MyGameEditorTarget with the same body except Type = TargetType.Editor; and ExtraModuleNames.AddRange(new string[] { "MyGame", "MyGameEditor" }); . BuildSettingsVersion.V7 is what 5.8 project templates emit ( Latest also equals V7 ). Pin the explicit value; Latest changes meaning on every engine upgrade. EngineIncludeOrderVersion.Unreal5 8 selects the UE ENABLE INCLUDE ORDER DEPRECATED IN 5 8 define that keeps removed implicit engine includes available to your code. Unreal5 1 – Unreal5 5 are [Obsolete] and unsupported; Unreal5 6 is deprecated. A module may override with ModuleRules.IncludeOrderVersion . BuildSettingsVersion Defaults it turns on V2 PCHUsage = UseExplicitOrSharedPCHs , bLegacyPublicIncludePaths = false V3 bLegacyParentIncludePaths = false V4 CppStandard default becomes Cpp20 , WindowsPlatform.bStrictConformanceMode = true V5 bValidateFormatStrings = true V6 WindowsPlatform.bStrictInlineConformance = true , UndefinedIdentifierWarningLevel = Error V7 (= Latest ) ReturnTypeWarningLevel , DanglingWarningLevel , UnreachableCodeWarningLevel = Error TargetType Builds Game Standalone game executable Editor Editor build; includes Editor type modules Client Networked client without server only code Server Dedicated server, no renderer Program Standalone tool (needs bCompileAgainstEngine / bCompileAgainstCoreUObject choices) Build configurations ( UnrealTargetConfiguration ): Debug , DebugGame (engine optimized, game unoptimized), Development (default), Test , Shipping . Useful target switches: bUseUnityBuild , bUseLoggingInShipping , bUseChecksInShipping , bWithLiveCoding , LinkType = TargetLinkType.Monolithic , GlobalDefinitions / ProjectDefinitions , and bOverrideBuildEnvironment = true to "ignore violations to the shared build environment (eg. editor targets modifying definitions)". .uproject File AdditionalDependencies is the descriptor's "list of additional dependencies for building this module". Plugin references accept Name , Enabled , Optional , TargetAllowList / TargetDenyList , PlatformAllowList / PlatformDenyList , TargetConfigurationAllowList . Module Types ( ModuleHostType ) Type Loaded by Runtime Any target using the UE runtime (the default for game code) RuntimeNoCommandlet Any target except commandlets RuntimeAndProgram Any target or program CookedOnly / UncookedOnly Cooked builds only / uncooked (editor, PIE) builds only — UncookedOnly is the type for Blueprint node (K2Node) modules Developer Only when developer tool support is enabled (deprecated: use DeveloperTool ) DeveloperTool Any target where bBuildDeveloperTools is enabled Editor / EditorNoCommandlet Editor only / editor but not commandlets EditorAndProgram Editor or program targets Program Program targets only ServerOnly / ClientOnly / ClientOnlyNoCommandlet Servers only / clients, commandlets and editor / clients and editor External Never loaded automatically; reference only Loading Phases ( ModuleLoadingPhase ) LoadingPhase When EarliestPossible As soon as plugins can load ( GConfig exists) PostConfigInit Right after the config system; very low level hooks only PostSplashScreen First screen after the system splash PreEarlyLoadingScreen After PostConfigInit , before CoreUObject initializes PreLoadingScreen Before the loading screen triggers PreDefault Right before Default — asset types, custom classes other modules need Default During engine init, after game modules load (most modules) PostDefault Right after Default PostEngineInit After the engine is fully initialized None Never auto loaded; use FModuleManager::Get().LoadModule() Creating a New Module Macro ( Modules/ModuleManager.h ) Use IMPLEMENT MODULE(FMyModule, MyModule) Modules without gameplay classes (tools, editor, libraries) IMPLEMENT GAME MODULE(FMyModule, MyModule) Modules that contain gameplay UCLASS es; expands to IMPLEMENT MODULE IMPLEMENT PRIMARY GAME MODULE(FDefaultGameModuleImpl, MyGame, "MyGame") Exactly one per game; in monolithic builds it defines the project name from UE PROJECT NAME ; the third argument is DEPRECATED GameName ( ModuleManager.h:1100 ) and unused FDefaultModuleImpl and FDefaultGameModuleImpl are ready made classes for modules with no startup logic; FDefaultGameModuleImpl::IsGameModule() returns true so hot reload tooling treats it as game code. The second macro argument must equal the Build.cs module name; both the monolithic and modular forms of the macro check it against UE MODULE NAME with UE STATIC ASSERT WARN ( ModuleManager.h:950 , :968 ), which emits a "Module name mismatch" deprecation style warning , an error only under bWarningsAsErrors . Other IModuleInterface hooks: PreUnloadCallback() , PostLoadCallback() , SupportsDynamicReloading() , SupportsAutomaticShutdown() . Then register the module in three places: the .uproject (or .uplugin ) Modules array, ExtraModuleNames in every Target.cs that should build it, and the dependency lists of modules that use it. Editor only modules ( "Type": "Editor" , PrivateDependencyModuleNames.Add("UnrealEd") inside if (Target.bBuildEditor) ) are covered in ue editor tools . Creating a Plugin Declare every plugin whose modules you depend on in Plugins ; UBT warns "Plugin 'MyPlugin' does not list plugin 'X' as a dependency, but module 'MyPlugin' depends on module 'Y'" otherwise. IsExperimentalVersion / IsBetaVersion are what the editor shows as maturity; EnabledByDefault: true enables the plugin in every project without a .uproject entry. Content only plugins omit Modules entirely and keep "CanContainContent": true . Game Feature plugins ( UGameFeatureData , actions) are owned by ue game features . The runtime module never includes editor headers; gate editor code with if WITH EDITOR and editor dependencies with if (Target.bBuildEditor) . Engine vs project plugins: Engine/Plugins/ is shared by every project on that install; <Project /Plugins/ travels with the project and wins on a name clash. Installed (Launcher) engines ship only precompiled engine modules: depending on an engine module that was not precompiled fails with "Missing precompiled manifest for 'X'. This module can not be referenced in a monolithic precompiled build, remove this reference or migrate to a fully compiled source build." Which Module Provides This Type Add to DependencyModuleNames For Plugin to enable Core FString , TArray , FName , UE LOG , FModuleManager — CoreUObject UObject , UClass , FInstancedStruct , reflection — Engine AActor , UActorComponent , UWorld , UGameInstance , UAudioComponent — InputCore FKey , EKeys — EnhancedInput UInputAction , UInputMappingContext , UEnhancedInputComponent EnhancedInput GameplayTags FGameplayTag , FGameplayTagContainer , UGameplayTagsManager — GameplayTasks UGameplayTask , UGameplayTasksComponent — GameplayAbilities UAbilitySystemComponent , UGameplayAbility , UGameplayEffect GameplayAbilities NetCore FFastArraySerializer , push model macros — DeveloperSettings UDeveloperSettings — Slate , SlateCore SWidget , SCompoundWidget / FSlateBrush , FSlateColor — UMG UUserWidget ,