Real plugins (discovered and loaded dynamically) in a packaged game

So it seems that by default, non-editor builds are monolithic, and monolithic seems to mean that even plugins are statically linked into the executable. Which means that in effect, runtime plugins are not really plugins at all, they are just a collection of modules like any other.

I’m wondering if anyone has attempted to create a UE4 game that can dynamically discover and load plugins in a packaged build? I would think ideally there should be a way to specify whether to link monolithically or dynamically on a per-plugin basis (or at least allow monolithic linking of engine and project modules, but leaving plugin modules to be dynamically loaded). From what I’ve seen of the source code and use of the IS_MONOLITHIC preprocessor macro, my guess is that currently it has to be either all or nothing in that respect, though.

So I’m assuming the only way to go at this point would be to force a completely modular build of the project. Has anyone attempted this, or have any other input on using truly dynamically loaded modules with UE4?

You can configure your game to compile in non-monolithic mode by adding the following to its *.Target.cs file:

public override bool ShouldCompileMonolithic(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration)
	return true;

That is how Unreal Tournament does it, and you can find several other examples for non-game programs in the engine code base.

Keep in mind that this will not work on all platforms though. For example, iOS does not allow dynamically loaded libraries.

Thanks for the info Gerke, I’m going to experiment with this.

I realised after posting though that what I wrote didn’t entirely make sense. Obviously, if you’re linking a plugin at build time, then be it monolithic or modular, the mere fact that it is part of the build process means it isn’t truly a plugin.

So I guess my real question is, will a monolithic build of a game still allow for dynamic discovery and loading of modules (unknown at build time) via the module manager? Or does this behaviour require a modular build in order for the module manager to be set up correctly?

I’m actually not sure. It might still work, but I haven’t tried it. The only problem is that the module won’t get built if UBT doesn’t know about it, but if it knows about it then it will get compiled into the executable.