So, after some tinkering I now have an inhouse distributed engine build, which works for building and packaging both Server and Client Targets. I also added an option to allow for a custom output directory.
I only altered the default InstalledEngineBuild.xml a little bit by adding the UE4Server and UE4Client targets as follows:
<!-- Ouput directory for the build. This was ADDED to the xml -->
<Option Name="BuiltDirectory" DefaultValue="$(RootDir)/LocalBuilds/Engine/" Description="Directory for outputting the built engine"/>
<!-- The local output directory. These were EDITED in the xml -->
<Property Name="LocalInstalledDir" Value="$(BuiltDirectory)/Engine/Windows"/>
<Property Name="LocalInstalledDirMac" Value="$(BuiltDirectory)/Engine/Mac"/>
<Property Name="LocalInstalledDirLinux" Value="$(BuiltDirectory)/Engine/Linux"/>
Later in the Target Platform Node I added:
<ForEach Name="Configuration" Values="$(GameConfigurations)">
<Compile Target="UE4Game" Platform="Win64" Configuration="$(Configuration)" Tag="#UE4Game Win64" Arguments="-precompile $(VSCompilerArg) $(TargetDebugInfoArg)"/>
<Compile Target="UE4Server" Platform="Win64" Configuration="$(Configuration)" Tag="#UE4Game Win64" Arguments="-precompile $(VSCompilerArg) $(TargetDebugInfoArg)"/>
<Compile Target="UE4Client" Platform="Win64" Configuration="$(Configuration)" Tag="#UE4Game Win64" Arguments="-precompile $(VSCompilerArg) $(TargetDebugInfoArg)"/>
</ForEach>
<!-- Some other stuff -->
<!-- Tag the generated includes for this target -->
<Tag Files="Engine/Intermediate/Build/Win64/UE4/Inc/...;Engine/Plugins/.../Intermediate/Build/Win64/UE4/Inc/..." With="#UE4Game Win64 Includes"/>
<Tag Files="Engine/Intermediate/Build/Win64/UE4Server/Inc/...;Engine/Plugins/.../Intermediate/Build/Win64/UE4Server/Inc/..." With="#UE4Game Win64 Includes"/>
<Tag Files="Engine/Intermediate/Build/Win64/UE4Client/Inc/...;Engine/Plugins/.../Intermediate/Build/Win64/UE4Client/Inc/..." With="#UE4Game Win64 Includes"/>
Then I built the Engine from Commandline using this command:
./RunUAT.bat BuildGraph -target="Make Installed Build Win64" -script="Engine/Build/InstalledEngineBuild.xml" -set:WithMac=false -set:WithAndroid=false -set:WithIOS=false -set:WithTVOS=false -set:WithLinux=false -set:WithHTML5=false -set:WithLumin=false -set:WithDDC=false -set:WithWin32=false -set:BuiltDirectory="PathToOutputDirectory"
As @ryanjon2040 mentioned you then have to copy over the UE4Server.Target.cs and UE4Client.Target.cs to your resulting Engine/Source/ folder.
(Also add the corresponding targets to your Project/Source/ folder.)
For packaging I use the BuildCookRun from commandline as follows:
./RunUAT.bat BuildCookRun -project="FullPathToProjectfile.uproject" -noP4 -platform=Win64 -clientconfig=Development -serverconfig=Development -cook -allmaps -server -client -serverplatform=Win64 -stage -pak -archive -archivedirectory="FullPathToOutputDirectory"
I think that was all I did. Of course you have to edit your Project with the UnrealVersionSelector to use the resulting Engine Binary. (Start UE4Editor.exe once so it can set the correct registry keys and is visible in the Version Selector)
Some other tips:
- To get your dedicated server to run with an anonymously logged in steamcmd.exe, you have to copy the four Steam .DLL files from your Engine directory (\Engine\Binaries\ThirdParty\Steamworks\Steamv139\Win64) next to your Server binary. Otherwise you will get SteamAPI Errors. (Source)
- The Server and Client have a version check integrated by default. Hereis a starting point on how to override it with your own stuff.
- My server was starting too fast sometimes and I had no time to attach my debugger. I added the following hack to my code, so now the process waits for the debugger if I use the command line parameter “-WaitForDebugger”.
//TODO SR: REMOVE THIS DEBUGCODE
if (FParse::Param(FCommandLine::Get(), TEXT("WaitForDebugger")))
{
UE_LOG(LogTemp, Verbose, TEXT("'WaitForDebugger' found. Waiting for Debugger."))
while (!IsDebuggerPresent())
{
Sleep(1000);
}
}
- Use command line arguments to start your server with logging. (e.g. ProjectServer.exe -log -logcmds=“logonline all, logonlinegame all”)
I hope this little summary helps anyone with the same problems. If anyone has questions, just ask in this thread or shoot me a message here or on twitter.
My next problem: How to change the Project Version number from my builders command line. (I hoped for some .ini setting that I could override in the packaging process, but I haven’t found anything yet)