Skip to main content

πŸ”Œ Lesson 8.3: Writing a C++ Plugin

A plugin is a self-contained bundle of modules, content, and assets you can drop into any project β€” enable it and its features appear. It's how you build reusable systems, share code across your games, and (if you like) publish to the marketplace. And it's built entirely from the module concepts you just learned.

🎯 Learning Objectives

By the end of this lesson, you will be able to:

  • Explain what a plugin is and how it differs from a bare module
  • Read a .uplugin descriptor and its module list
  • Describe a plugin's folder structure
  • Create a plugin with the editor's plugin wizard
  • Decide when a plugin beats a module, and enable/disable plugins

Estimated Time: 60 minutes

Engine Version: Unreal Engine 5.8

In This Lesson

Plugin vs Module

A module (Lesson 8.1) is a unit of compiled C++ inside a project. A plugin is a portable package that contains one or more modules, plus its own content, assets, and descriptor β€” and can be moved between projects as a folder.

graph TD P["Plugin (MyInventorySystem)"] --> M1["Module: MyInventorySystem (Runtime)"] P --> M2["Module: MyInventoryEditor (Editor)"] P --> C["Content/ (its own assets)"] P --> D[".uplugin descriptor"]
Figure 1: A plugin bundles modules, content, and a descriptor into one portable unit. Copy the plugin folder into another project, enable it, and everything comes along.

πŸ“– The key difference: portability & toggling

A project module lives in that project. A plugin is self-contained and toggleable β€” enable/disable it in the Plugins browser, ship it independently, reuse it across every game you make. You've already used many: Enhanced Input, and (from your own course) the Unreal MCP plugin are exactly this β€” bundled modules you enable. Now you build your own.

Plugin Structure

Plugins live in a Plugins/ folder (project-level or engine-level). Each plugin is a folder mirroring a mini-project:

Plugins/
└── MyInventorySystem/
    β”œβ”€β”€ MyInventorySystem.uplugin      # the descriptor (metadata + module list)
    β”œβ”€β”€ Source/
    β”‚   └── MyInventorySystem/
    β”‚       β”œβ”€β”€ MyInventorySystem.Build.cs
    β”‚       β”œβ”€β”€ Public/                 # the plugin's API (Lesson 8.1)
    β”‚       β”‚   └── InventorySubsystem.h
    β”‚       └── Private/
    β”‚           └── InventorySubsystem.cpp
    β”œβ”€β”€ Content/                        # optional: the plugin's own assets
    └── Resources/                      # icon, etc.

βœ… It's modules all the way down

Notice the Source/, Build.cs, and Public/Private layout β€” identical to Lesson 8.1. A plugin is modules plus a descriptor plus a home for content. Everything you learned about modules applies directly; the plugin just wraps them for portability. The Public/Private split especially matters here, since a plugin's public headers are the API other projects consume.

The .uplugin Descriptor

The .uplugin file is JSON that describes the plugin and lists its modules β€” the plugin equivalent of the Modules section in a .uproject (Lesson 8.1).

{
    "FileVersion": 3,
    "Version": 1,
    "VersionName": "1.0",
    "FriendlyName": "My Inventory System",
    "Description": "A reusable inventory subsystem.",
    "Category": "Gameplay",
    "CreatedBy": "Ray de la Paz",
    "EnabledByDefault": true,
    "CanContainContent": true,
    "Modules": [
        {
            "Name": "MyInventorySystem",
            "Type": "Runtime",
            "LoadingPhase": "Default"
        },
        {
            "Name": "MyInventoryEditor",
            "Type": "Editor",
            "LoadingPhase": "PostEngineInit"
        }
    ]
}
FieldMeaning
FriendlyName / DescriptionShown in the Plugins browser
CanContainContentWhether the plugin ships its own assets
ModulesThe modules it contains, with Type & LoadingPhase (Lesson 8.1)
Plugins (optional)Other plugins this one depends on

πŸ“– Runtime + Editor module split

A well-structured plugin often has a Runtime module (ships in the game) and a separate Editor module (tools, custom asset editors β€” never shipped). Same target-type separation as Lesson 8.1, now inside a portable package. This keeps editor-only code out of your packaged game automatically.

Creating a Plugin

You rarely write the boilerplate by hand β€” the editor generates it. From Edit β†’ Plugins β†’ Add (or "+ Create Plugin") β†’ choose a template (Blank, Blank with content, Editor Toolbar Button, etc.), name it, and Unreal scaffolds the .uplugin, Source/, module class, and build file.

The generated module implements IModuleInterface (Lesson 8.1) so you have startup/shutdown hooks:

// MyInventorySystem.cpp β€” generated plugin module.
#include "MyInventorySystem.h"
#include "Modules/ModuleManager.h"

#define LOCTEXT_NAMESPACE "FMyInventorySystemModule"

void FMyInventorySystemModule::StartupModule()
{
    // Plugin loaded β€” register any plugin-wide systems here.
}

void FMyInventorySystemModule::ShutdownModule()
{
    // Plugin unloading β€” clean up.
}

#undef LOCTEXT_NAMESPACE

IMPLEMENT_MODULE(FMyInventorySystemModule, MyInventorySystem)

⚠️ Enable it, and regenerate

After creating (or copying in) a plugin, make sure it's enabled in the Plugins browser and listed in your .uproject's Plugins section, then regenerate project files and rebuild (Lesson 1.3). A plugin whose modules aren't building is almost always disabled or not regenerated β€” the same fix as most module issues.

When to Use One

Use a plugin when…A plain module is enough when…
You'll reuse the system across multiple projectsThe code is specific to this one project
You want it toggleable / optionalIt's always part of the game
It ships its own content/assetsIt's pure gameplay code in the main module
You'll share or sell it (marketplace)It stays internal
You want a clean, isolated feature boundaryTight coupling with game code is fine
πŸ’‘ The reuse test: "Would I want this in my next game too?" If yes, build it as a plugin from the start β€” retrofitting a project module into a plugin later is more work than starting clean. A well-factored inventory, dialogue, or ability system is a natural plugin; a specific boss's AI is not.

Hands-on Exercise & Quiz

πŸ‹οΈ Exercise: Package the inventory

Objective: Plan turning the inventory subsystem (Lesson 7.4) into a reusable plugin.

  1. Sketch the plugin folder structure for InventoryPlugin containing the UInventorySubsystem.
  2. Which folder does InventorySubsystem.h go in so other projects can use it, and why?
  3. Would you add a second Editor module? What might it hold?
  4. What's the "reuse test" answer that justifies making this a plugin?
βœ… Answers
  • Structure: Plugins/InventoryPlugin/ with .uplugin, Source/InventoryPlugin/{Build.cs, Public/, Private/}, optional Content/.
  • InventorySubsystem.h β†’ Public/, so dependent projects/modules can include it (Lesson 8.1 Public API).
  • An Editor module could hold a custom inventory editor window or a DataAsset editor β€” editor-only, never shipped.
  • Inventory is a system you'd want in many games β†’ yes, a plugin from the start.

🎯 Quick Quiz

Question 1: How does a plugin differ from a plain module?

Question 2: What does the .uplugin file contain?

Question 3: A system you want reusable across several of your games is best built as:

Summary

πŸŽ‰ Key Takeaways

  • A plugin bundles one or more modules, optional content, and a .uplugin descriptor into a portable, toggleable unit.
  • Its structure mirrors a module (Source/, Build.cs, Public/Private) plus Content/ and the descriptor β€” modules all the way down.
  • The .uplugin JSON lists modules with Type/LoadingPhase; a common split is a Runtime module + an Editor module.
  • Create with the plugin wizard; enable it in the Plugins browser and regenerate project files.
  • Reach for a plugin when a system is reusable, toggleable, or shippable; a plain module suffices for project-specific code.

πŸ“š Additional Resources

πŸš€ What's Next?

Module 8 is complete β€” you can structure, extend, and package C++ at the project level. Module 9 returns to gameplay-facing work: driving UMG user interface from C++, so your HUDs and menus are code you control.

πŸŽ‰ Module 8 complete!

Your code is organized, extensible, and packageable. Let's build some UI.