Using Perforce/GitHub/UE4ProjectDirs is sticky

Hey everyone,

We’ve been having a little trouble dealing with engine modifications and integrating new versions of the engine along the way using GitHub. There seems to be 2 inconvenient options, I’m going to try and go over the really sticky parts here.

Option 1
Treat your game project the same regardless of weather it is intended to be used with a source engine build or a prebuilt binary build.

/Depot/Game/
/Depot/Engine/4.2/
/Depot/Engine/4.3/
/Depot/Engine/4.4/

The Good

  • Engine is easily upgraded, you can pull a build from Git Hub, check it into a new Engine subdir, integrate in your custom sauce and go, upgrade your game project check-in and god.
  • Game code is clearly isolated from engine code
  • Integrations can be trusted

The Bad

  • EngineAssociation in your Game.ueproject file is always wrong and needs to be upgraded because the GUID used in engine identifier is not checked-in and changes from machine to machine.
  • Visual Studio Solution/Projects only partially complete and do not include shaders and some other bits that are necessary when building the engine from source for custom sauce.
  • UnrealVS is hosed and doesn’t work correctly, can’t refresh your projects.

Option 2
Use .ue4projectdirs this works great if you have full P4 history.

/Depot/Game/Game.uproject
/Depot/.uprojectdirs

The Good

  • Engine works correctly in all cases because this is the prescribed setup used internally by Epic
  • All engine source files are available in solution
  • UnrealVS works as intended, can regenerate project files

The Bad

  • The biggest problem here is that engine code is difficult to integrate using GitHub and is missing stuff from the history, this is the primary source of our problems.
  • Game code is buried in engine directory
  • Game ends up in a solution named UE4.sln

This config has 3 teirs of success.

1 - You’re Epic Games
- You can integrate the engine over-top of your games because you can easily and see the full P4 history, and are able to handle deletions/moves correctly
- You own the engine codebase, the engine makes sense to sit on top of everything because it’s the foundation for your entire company

2 - You’re a top tier developer with P4 access to Epic.
- You can integrate the engine over-top of your games because you can easily and see the full P4 history, and are able to handle deletions/moves correctly

3 - You’re a subscription user
- Git Hub only provides source and doesn’t track changes to the binaries
- Integration over-top of an existing game/engine combo is not trustworthy and doesn’t effectively track deletions and moves
- Delete everything -> unzip -> reconcile offline work is stupid and doesn’t handle integrations

In order to make this work, we've resorted to this workflow

Initial game/engine drop
/Depot/Engine_4.1/.uprojectdirs
/Depot/Engine_4.1/Game/Game.uproject

Create new engine root Engine_4.2
/Depot/Engine_4.2/.uprojectdirs
Integrate changes from 4.1 -> 4.2
Move Engine_4.1/Game/ to Engine_4.2/Game/

Create new engine root Engine_4.3
/Depot/Engine_4.3/.uprojectdirs
Integrate changes from 4.2 -> 4.3
Move Engine_4.2/Game/ to Engine_4.3/Game/’

Now performing the integration isn’t the issue, you need to do that if you’re making changes of-course which is why we chose this path. The ******* is having to leapfrog your game dir from engine dir to engine dir. Maybe there is something we’re missing about doing the P4 integration but I don’t think so. Integrating a new historyless drop of the engine into a historied directory treats the new drop as law and you’ll overwrite changes. So you have to go the other way CUSTOM_SAUCE_ENGINE -> FRESH_ENGINE_DROP.

Solution?

Our preferred structure would be Option 1. It helps to keep integrations from GitHub/ZipFiles simple and avoids constantly moving the game dir.

I to propose the following steps to resolve the issues and allow game projects used with engine source to exist outside the engine directory.

  • Game projects used with engine source will have all source/shader and other ancillary files added to soulution/vcproj (should look like ue4.sln). Game source projects that do not use engine source will use the existing behavour.

  • A file placed in the engine source root (lets call it ue4identifier.txt) contains a single line which is the unique identifier used to identify this version of the engine. If this file is then checked in you now have a static identifier across your team rather than a random GUID.

I’ve already poking at the engine association change. I’m going to continue down this path and make a PR once I’m done unless there is a better alternative.

Edit:

Another solution here would be to support .uprojectdirs that could map to a relative path outside the engine root. The issue here comes from the foreign project concept. Something there would need to be extended to support this structure. I’m not sure which solution is better at this point.

Thanks!

/ Kyle

So after some investigating, it appears that there is a simple bug remaining in UProjectInfo.cpp

Specifically, the FUProjectDictionary() constructor doesn’t convert project paths found in *.projectdirs to absolute paths. However, all the other checks including the one in IsForeignProject checks against absolute paths (a fix that was only made very recently). Based on the assumption that all this is supposed to be based on absolute paths, I’ve made the fallowing change/pull request. This does solve our issue and allows you to point the uprojectdirs at a project anywhere else in the tree.

https://github.com/EpicGames/UnrealEngine/pull/453

Cheers!

/ Kyle