Functioning UE4 Modding Example Code - No Engine Customization Required

Maybe I’m not understanding something right, but after some more testing, it appears as though you have to have the original project files in order to create a mod. Your example, has both the main program and the mod in the same project together, which works fine in that simple case. However, in a real life case, the end user won’t have access to the main program. They would need to create a new project in UE4, create their mod and then cook it. This is where it seems to fall apart.

I was able to get a separate project working as a mod. However when I go to cook it in the project launcher I get errors as it cannot locate the 1.0 release of the main program. It appears as though there needs to be a Releases folder in the mod project with the 1.0 release inside it. However you only get that after you cook the main program, which obviously an end user won’t be able to do.

So I tried copying the Releases folder across from the main project to the mod project and it was able to get further, however then it started throwing a whole lot of warnings about not being able to resolve packages for the assets in the main program and it doesn’t create the cooked data.

Have you been able to actually create and cook a mod in a separate project from the main project?

I think it should be possible with content-only mods. Consider the following two scenarios:

Let us say you distribute “GameBinary”. An end-user could download the vanilla UE4 Editor, create a new “EmptyProject”, and a new “ModPlugin”. They could add content (textures, static meshes) to “ModPlugin”. Then they would need to build the main “EmptyProject” (1.0), then build the “ModPlugin” DLC to obtain the .pak and AssetRegistry.bin files. “GameBinary”, given logic similar to ModSkeleton, should be able to load up the .pak file (even though it was built against a different base release) and merge the .bin file into the in-memory AssetRegistry, through which you could search to find the additional content.

  • this does not address logic, c++ or Blueprints

Now, let us say you have “GameProject2” based on “ModSkeleton”. You can choose to add base classes (like “AWeapon”) to your main project for a more traditional experience, or try to invoke all extension logic through the hook system. You can add proprietary content and logic to any number of DLC plugins that you keep internally. You can build the main “GameProject2” resulting in “GameBinary2”. You can build your proprietary plugin DLC and distribute the resulting .bin and .pak files with your binary.

For end-user modding, you would need to distribute the “GameProject2” source… but NOT your proprietary plugins. End-users would indeed need to build the main “GameProject2” (1.0) first, before they could build any new mod plugins they had created.

Cntent plugins wouldn’t work though as I’m hoping to have blueprints in the mods that extend from base classes. I like your second idea and it sounds good in theory, but I see one big problem with that approach, unless you can think of a way around this. As far as I’m aware, plugins cannot directly access content, blueprints, classes, etc, defined in the main project. Therefore if you added your base classes (i.e. AWeapon) to the main project, then the plugin DLC/mod would not be able to see it and would not be able to derive new weapons from it. So I think that method breaks down completely, unless I’m wrong?

So long as you’re willing to distribute your main project to end-user mod creators, they should be able to derive / subclass anything you give them. ModSkeletonExamplePluginA has 2 Blueprints (MOD_SKELETON and ExampleStringGeneratorHelper) that implement ModSkeletonPluginInterface which is defined in C++ in the main project.

The next thing I’d like to add to the ModSkeleton repo, is an example C++ plugin to prove out C++ inheritance.

I didn’t realise plugins could access content from the main project. I assumed it was one-way only. I have no problem distributing the main project. I would just need to go through the huge task or breaking my proprietary content/logic out into a core mod as you pointed out and just keep the base classes in the main project.

I’ve had a bit of a fiddle with it but am struggling to get it to work right. I’ll give you the scenario. Maybe you have an idea?

I have a main project called MyProject and a mod plugin called MyMod. The main project has a base class in it called MyBaseClass. The main project has your code to scan for pak files and add them to the asset registry. I then have some additional code that checks every asset in the asset registry and logs any blueprints that derive from MyBaseClass.

In the main project I created two blueprints derived from MyBaseClass called, MyProjectTestA and MyProjectTestB. In the mod plugin I created one blueprint derived from MyBaseClass called MyModTestA.

I then followed your steps of building the main project and then building the mod plugin using the custom profiles. I renamed and copied the bin and pak files over for the mod and finally ran the executable. However the mod content, MyModTestA never appears in the asset registry. Here is a snippet from the log. Note the extra lines that list the assets found in the asset registry after the mod plugin has been loaded.

ModSkeletonLog: Searching for Pak AssetRegistries: …/…/…/MyProject/Content/Paks/*.bin
ModSkeletonLog: - AssetRegistry: …/…/…/MyProject/Content/Paks/MyMod.bin
ModSkeletonLog: Attempting PakLoad: …/…/…/MyProject/Content/Paks/MyMod.pak
ModSkeletonLog: - Mounting At: …/…/…/MyProject/Content/Paks/Plugins/MyMod/Content/
ModSkeletonLog: - AssetRegistry Loaded (24 bytes): …/…/…/MyProject/Content/Paks/MyMod.bin
ModSkeletonLog: Found ClassName: MyProjectTestA_C
ModSkeletonLog: Found ClassName: MyProjectTestB_C

So it seems that the mod pak is being found and loaded as it is hitting all the right log entries in your code. However when I scan the asset registry for all assets that derive from MyBaseClass, it only finds the two assets from the main project. Any ideas?

Also, do you know of a way to run this from Visual Studio so I can step through the code? When I try and run it from Visual Studio I just get a bunch of “Error: CDO Constructor (<some engine component>): Failed to find /Engine/<some engine content>” errors regarding engine content if I have the mod plugin bin and pak files in the Content/Pak folder. If I remove the mod bin and pak files, then it runs fine.

  • First, you may want to verify that your class is making it into the mod .pak:

  • Second, I personally keep having problems working with the registry in how blueprints actually inherit from UBlueprint instead of the native c++ class they come from. You may want to consider inverting your workflow. That is, ModSkeleton provides a path for invoking an init function on a blueprint loaded from a mod, so long as it implements the interface. Once you are inside running code, you have a lot more options. You could create an array of MyBaseClass references on some global object (gameinstance, etc…) and from within your mod init function append all the derivative classes that are included in your mod plugin.

I’m working on modularizing the ModSkeleton repo, to provide distinct examples that are easier to work through from start to finish for accomplishing things like this. If you would like to see an interim commit, I have a working example of a base c++ actor class in the main project (ATestActorBase), and a Blueprint subclass in the mod-plugin (TestActorExampleA), with an interface function that is spawned and executed at runtime, invoking the super function up the chain:

Alas… I’m a linux guy. I know how to work with gdb : )… I do need to figure out how to debug with VS eventually, but so far, I’ve just been debugging with logging.

Ah ha… After extracting the pak file, it only had the asset registry bin file and some other json file in it. No other asset content. So I’m guessing my test content in the plugin is being ignored because it is not being referenced anywhere in the project. I tried using “Additional Asset Directories to Cook” but that only lets you add sub folders of the main project’s Content folder. No plugin folders allowed. So I tried ticking “Cook everything in the project content directory” but that option then fails to produce a pak file at all, and by the name I’m guessing it only applies to the main project anyway. Do you know how to force content in the plugin to be cooked and added to the pak?

I’ll take a look at your updated repo as I’m guessing you got it to cook your TestActorExampleA from the plugin and I’m assuming your not directly referencing that asset in the main project? So you must have some setting set somewhere? I have no idea where to look though.

I just double checked my settings, and as far as I can tell, everything related to packaging is un-changed from the project template. You are correct that I am not referencing the plugin content from the main project. Other than making sure to disable the plugin while building the main project, and re-enabling it for building the DLC, I can’t think of anything else to try.

If you have a test project you don’t mind sharing, I could take a look to see if anything jumps out.

I just merged in a build script that runs UE4 tools directly to build both the main project, and any DLC plugins you specify, without the need to create custom launcher profiles.

You can see the usage notes in the ModSkeleton/README.md :

Hey that’s pretty cool. Will check it out. I haven’t had a chance to get back to my issue with building DLC yet.

Thanks Neonphog for the script! Will try it immediatly!

For everyone else. Lets hope Epic hears us out. I created a suggestion thread to request epic makes modding system much more friendly to users and us developers.

Hi, dumb question. How do I run the ue4build.js using node? I dragged to the console command window of node and pressed enter but it’s not working.

http://puu.sh/va9iz/0599f267ef.png

Edit. Got it.

Shift Click where ue4build.js is, then open comand window here, and just do the node ue4build.js

OMG! I just got it working! after almost 2 months of struggle. I managed to upload an item to the workshop. everything is hard coded, and I gotta do a bunch of test to see how it downloads and stuff, but ****!

8c9463fe6e5c3b0393cae9209ad5602f7d820375.jpeg

Neat!