Sharing code between UE projects, best practices?

I’m about to spawn off some more game projects based on work I’ve already done for my first UE4 project (which was based on some custom engine I had started well before I got into UE).

One thing I’m curious about is the simplest and most robust way to do this, and if others have experience with maintaining code modules between multiple projects.

I’ve got three layers to my onion…

  • non-UE4 C++ code for gameplay, animation, AI that is platform and engine agnostic

  • this code sits outside of my UE4 game’s source folder, I use a script to create .cpp references so it’s compiled in (see below)

  • C++ code that is UE4 engine dependent, but should be re-used across different games

  • this code sits inside of the UE4 game’s source folder

  • C++ code that is game and engine specific and doesn’t need to be shared

  • also inside the UE4 game’s source folder

What I’m doing right now…

I have a Python script that creates .cpp files with-in the project’s Source directory that #include’s the .cpp file located outside of the Unreal game project directory. Not crazy about it, as I need to re-run the script anytime I move/delete/add source files outside the project, but it is simple and robust.

#define SG_UNREAL 1
#define PLATFORM_WIN 1
#include "C:\\Repo\\Library\\AppLib\\Source\\MyAudio\\MyAudio.cpp"

Not currently using any game or engine plugin for any of the code I’ve written.

What I’m thinking about doing…

Setting up the library code as an Unreal Engine plugin so it can be shared across projects much easier.

The only downside I can think of is I need to setup a separate git repo. Or do what I’m doing above, creating the stub include cpp files, in an engine plugin.

Wanted to hear other C++ devs opinions and experience on code sharing between Unreal projects.

Based on my experience of this, it rarely works out very well.

It’s definitely beneficial to split common code out into their own modules or plugins, over the years I’ve created a few of these that I often import into new projects straight away (such as my own math functions, or useful types and classes etc) - but actually sharing the same code files between projects is a bad idea. As soon as Project 2 needs to modify it for whatever reason, Project 1 is now broken. No matter how well you think that code has been made, it will need maintenance and changing.

It becomes an even bigger problem as projects switch between different engine versions, where it’s basically unmaintable without massively increasing your workload.

I tried adding an engine plugin, but now it won’t let me launch the project because the plugin isn’t compiled. And I can’t figure out how to compile the plugin with-in the engine file structure. Do I have to include the plugin in the game folder for it to compile?

You put the plugin in MyProjectRoot/Plugins/

Git submodules.

I might have figured out a better solution than my stub .cpp #include files, or mucking around with plugins.

Using Windows’ mklink, I can trick Unreal into thinking the external folder is actually inside of the project’s source folder by setting up a directory junction…

mklink /j MyUnreal \MyRepo\Library\MyUnreal\Source

Much less maintenance (I hope) and the source code correctly shows up in the IDE solution.

Well like I say… it’s less maintenence until one of your projects falls behind or uses a different engine build.

Yeah, I’ve had that happen before. Mainly due to SDKs coming and going (remember OpenFeint?). I’ve learned over time to be careful about integrating things that might go away so they can easily be pulled out or replaced with minimal fuss.

The idea though is to keep as much of the different projects in the common spaces as possible so if one advances versions then the others are most of the way too. Background, I’m building one sports game (rugby) that is also acting as the framework/prototype for other sports games. The more I can share between projects, the easier my life (in theory) gets down the road.

It works!

I did get tripped up with one issue, making sure that include paths in the .Build.cs file were looking at headers thru the linked directories (not directly at the repo files), otherwise the compiler got confused looking at the same header via two separate paths (even tho they resolve the same).

BAD: PublicIncludePaths.Add( “C:\MyRepo\Library\MyCore\Source” );

GOOD: PublicIncludePaths.Add( “Rugby\MyLink\MyCore” );

This sounds worth a try.

But yeah, we’ve taken several attempts a using either plugins or DLLs to make core code more modular. Never really amounted to significant compile time reduction or maintenance reduction.

Usually a new project == create core skeleton framework in latest version, then start adding features. It actually works fairly well to refine core code and strip unused cruft not needed in new project.