Time to rethink the UE4 Visual Studio solution structure?

It occurred to me that the way the UE4 VS solution is structured is a bit bizarre. The entire engine, with all of its plugins and modules, is packed into a single project that outputs dozens of dlls. Likewise the game itself is packed into another project, along with all project-specific plugins and modules. Only the supporting programs (shader compiler, UBT, UAT, etc) get to be placed in their own projects. This has a few drawbacks.

First, you cannot easily limit the scope of a “find in files” search to a specific module/plugin. Setting the search scope to “current project” in the UE4 project will search across all modules and all plugins. On the game project any project-specific plugins are also included in the search.

Second, you cannot easily rebuild a single module dll.

Third, I suspect this structure may play a part in Intellisense’s abysmal performance on the UE4 codebase. I recently had to dabble with the CryEngine source and was surprised by how much faster Intellisense was on it. It was even possible to use “find all references”, which takes so long to produce results in UE4 that I’d rather do regex searches across the whole solution/project. The ~20% difference in codebase size doesn’t seem to explain such massive performance difference, which led me to suspect the fact CE’s more traditional one-project-per-dll structure might have something to do with this.

UE4’s monolithic project creates a massive list of external dependencies and from Visual Studio’s perspective the separation between modules doesn’t exist: a function declared in a .h file could have its implementation in any one of the thousands of .cpp files that make up the entire engine, even if compilation-wise it could only possibly exist in the files that belong to that header’s module. I’m not too knowledgeable in the inner workings of Intellisense, but I suspect having a an include search path list with over 2300 entries doesn’t make it’s job any easier.

I’ll see if I can set aside some time to toy with the UBT VC project generation code and see if there’s any gains using a structure where each module has its own project, but it would be nice if I could get someone at Epic to think about this.

You can replace the slow intellisense stuff with visual assist. It runs 100s of times faster, thus has no problems at all with the unreal projects, and gives you better results aswell. Pretty much everyone working with unreal uses it.

+1

$99 a year isn’t too bad. Gotta get it. Then definitely follow the Epic instructions for completely disabling Intellisense - even if you have VAX installed Intellisense will run in the background slowing everything down until you beat it to death in the settings.

I agree modules should build to separate DLL files… But then they have to provide multi-platform build target support so things stay the way it is.

Could you provide a link for that? All I found were instructions to explicitly enable intellisense : Setting Up Visual Studio Development Environment for C++ Projects in Unreal Engine | Unreal Engine 5.3 Documentation

Follow the instructions in the second part of this page: Improve IntelliSense with Unreal Engine 4 (UE4)
(Below “If default IntelliSense is too slow for your development”)

Here’s the Epic version too: https://docs.unrealengine.com/latest…alStudioSetup/

Modules were always built as separate DLL files (or separate LIB files for static linking). That’s why they are called “modules” in the first place. The Visual Studio solution exists only for code editing purposes, actual building is handled through UBT.

I’m aware of VAX for faster intellisense, but it still doesn’t mean the situation couldn’t be better. Any changes to project structure that bring gains to Intellisense would also speed up VAX code completion.

When you package the game every lib goes into the monster exe file.
It’s common for most engines to split everything in packaged dlls, for windows at least; Only Unreal have this weird custom build system with a ton of hidden details in it.

Are there any clear advancages of having many dlls vs single monster exe? Programmers (like me) may like certain structure, but to gamers or users of your software, it doesnt matter.

However, I would really like to see the fat executable size get trimmed - the game is not that large, but the size is close to 50MB…

Static linking everything into single executable have advantage of not missing any dependencies. Everything is included.
Downside is obviously file size, but that’s only issue on mobile.

Though I agree, that generating solution, where every module is seprate project would ease on intellisense and searching. The downside would be making people think they can compile individual modules, while in reality they can’t.

Beyond trimming exe size ? No.

Static linked exe is actually smaller than the game + all dependencies as dlls would be, since unused parts of the dependencies are compiled out.

Development of game patches and patch file sizes could become significantly smaller and easier to do although the real culprit on that end is the structure of PAK files when a chunk has changed…
​​​​​

I don’t know why PAKs can’t be unencrypted, unarchived, have a handful of uassets updates and patches applied and then have them re-archived and encrypted. Is it a security problem for this to be done on the client? I guess so.

So what’s wrong with a straight PAK to PAK diff patch? And if it fails checksum use p2p to fetch the correct portions of it and reconstruct just the chunks that are invalid.

Someone make this tool, we’ll all give you money.

The difference in intellisese performance compared to CryEngine is so large it warrants investigation, at least. I use both daily and it’s shocking, it almost feels like I’m working with C# when I’m making changes to CE source code. Even changes to “hot” header files show up in reasonable time.

You’re right the UBT doesn’t really support building individual modules internally, it always goes through everything.

I am not sure, but I think PAK encryption uses public/private key pairs. If so, the shipping executable is only capable of decrypting PAK files and cannot encrypt them. But based on the 4.19 preview, it seems there are new options to control how encrypted you want your PAK files (I saw something about encrypting only config files but not the uassets themselves to make patching easier).

I don’t know if this anything to do with the structure but I notice that even a small UE C++ project takes ages to start up because of the many DLL files it loads. That is the worst for me since I often close and restart my UE program due to the fact that I dont use the compile from UE feature. I don’t trust it because it has already failed me many times and then I had to leave anyway and delete everything manually before rebuild

Well, it should be ages minus 15 seconds in 4.19 - this commit promises substantial improvement :wink:
https://github.com/EpicGames/UnrealEngine/commit/88401e57506eb6482f48defaeae4e27dea3a23ef

I tested compiling this commit and didn’t notice any change in loading times. Still takes > 10 seconds…

I assume it’s 15s in the worst case scenario. My loading times never were that bad and consequentially I didn’t see that big of a gain.