Project setup: modules, Build.cs, redirects

Course days 1–2 and GitHub setup · WadOfGore commit f27f647 · 5 min

In one breath

Your game's C++ is a module. WadOfGore.Build.cs says which other modules it may use. If you #include something from a module that isn't listed, you get a linker error, not a compile error. The redirects in DefaultEngine.ini are why Blueprints copied from the lecture project still find their C++ parent classes after the rename.

What a module is

A module is one unit of compiled code: one DLL in the editor. Your project has one, WadOfGore. The engine itself is hundreds of modules: Engine, EnhancedInput, GameplayAbilities and so on.

Build.cs: dependencies

Why it's C# at all: How Unreal builds your code.

PublicDependencyModuleNames.AddRange(new string[] {
    "Core", "CoreUObject", "Engine", "InputCore",
    "GameplayTags", "EnhancedInput", "GameplayTasks", "GameplayAbilities"
});

Each lesson that brought in a new system also added a line here: tags → GameplayTags, input → EnhancedInput, GAS → GameplayAbilities + GameplayTasks (abilities run tasks, so GAS needs it).

ListMeaningUse when
PublicMy headers include this module's headers, so anyone who includes me needs it too.A type from that module appears in your .h (e.g. UAbilitySystemComponent as a base class).
PrivateOnly my .cpp files use it.Only used inside implementation. Keeps other modules' builds lighter.

A game has one module, so putting everything in Public costs nothing. It matters once you write plugins with several modules, like your ModularShapes plugin.

Plugins are separate. GameplayAbilities is a plugin, so it also has to be enabled in the .uproject. That turns the plugin on; Build.cs lets your code link against it. You need both.

The redirects

+ActiveGameNameRedirects=(OldGameName="/Script/GOW",NewGameName="/Script/WadOfGore")

A Blueprint stores its C++ parent as a path like /Script/GOW.WarriorHeroCharacter (module name + class name). You renamed the module from GOW to WadOfGore, so without this line every copied Blueprint would lose its parent class and fail to load. The redirect tells the loader "anything that says GOW now means WadOfGore."

Related: Core Redirects ([CoreRedirects], +ClassRedirects) do the same job when you rename a class or a property rather than the whole module.

Your project

Your baseline commit message explains the fork: structure copied from the lecture reference, renamed to its own module, "lecture work gets ported in by hand from here on, not merged". Typing it in yourself instead of merging it is also the better way to learn it.

Quiz yourself

Answer in your head, then tap.

You add #include "AbilitySystemComponent.h" and use it, but forgot to add GameplayAbilities to Build.cs. What kind of error do you get?

Usually an unresolved external symbol (a linker error), or "cannot open include file" if the include path isn't set up. The compiler needs the header; the linker needs the module's compiled code. Build.cs provides both.

Public vs Private dependency: which one when a type from that module appears in your header?

Public. Anything that includes your header also needs that module's headers.

Why did the copied Blueprints need ActiveGameNameRedirects?

Blueprints reference their C++ parent by /Script/ModuleName.ClassName. The module was renamed GOW → WadOfGore, so the old paths would fail to resolve without a redirect.

What does WADOFGORE_API do?

It exports the class from the module's DLL, so other modules can link to it.

GAS is enabled in the .uproject. Why add it to Build.cs as well?

The .uproject enables the plugin, meaning it gets loaded. Build.cs lets your module compile and link against it. They are two separate steps.