
This is the second session in a three-part webinar series on Unreal Engine 5 workflows with Assembla and Visual Assist. Today’s presenters are John Scott, chief architect at Assembla with over 35 years of game development experience including 20 years with Unreal Engine and time as a senior programmer at Epic Games, and Montana Mendy, solutions engineer at Assembla.
This session demonstrates downloading Unreal Engine 5 source from GitHub and adding it to a single tenant Perforce instance in Assembla. The focus is on building practical workflows using Perforce streams for version control, configuring security properly, and setting up branching strategies that scale with team development.
Watch the webinar replay here.
Table of Contents
Hardware Requirements for Source Compilation
Before proceeding, Scott emphasizes the hardware demands of compiling Unreal Engine 5 from source. The machine used in this demonstration includes a Threadripper Pro with 32 cores and 64 threads, 128 GB of RAM at 3200 MHz, and 5 TB of NVME storage.
According to Scott, the goal is approximately 2 GB of RAM per CPU thread for compilation. NVME storage is critical for compile times. Scott recommends hardware of this caliber, warning that “otherwise, you’ll be spending the vast majority of your day waiting for compilation to finish.”
Without powerful hardware or a build farm, source compilation becomes impractical for daily development.
Linking Epic Games and GitHub Accounts
The first step requires creating an Epic Games account and a GitHub account, then linking them. Scott walks through the process: go to epicgames.com, click on your profile, navigate to Account, select Linked Accounts, and choose GitHub. Follow the instructions to authorize the connection.
Epic Games will send an email welcoming you to the Epic Games GitHub repository. This grants access to the Unreal Engine 5 source code.
Downloading Unreal Engine 5 Source
After linking accounts, Epic sends an invitation to the organization on GitHub. Scott navigates to the Unreal Engine branch and downloads the source code. He notes that clicking “Open in GitHub Desktop” still uses Git, which isn’t helpful when the goal is using Perforce, so he downloads the ZIP file instead.
The download and decompression take approximately 15 to 20 minutes depending on internet connection speed. Scott creates a dedicated folder structure for the engine source.
Once decompressed, the next step is running Setup.bat
from the engine source directory. This downloads necessary dependencies and takes considerable time to complete.
Critical Advice Before Compilation
Scott offers important guidance here. “At this point, you’ll be tempted to run generate project files, load in the project, and try to compile it. I would recommend that I would check everything in first so you don’t check in any temporary files.”
This prevents generated and temporary files from polluting the repository.
Creating and Configuring the Perforce Depot
Scott connects to a Perforce server that Andre (from Assembla’s team) prepared for the demonstration. He creates a new depot and explains why streams are essential.
“We want it to be stream,” Scott says. “We definitely for better branching strategies down the road.”
The depot is created as a stream depot, which enables the branching model that supports multiple engine versions and development workflows.
Securing Your Perforce Server
Before setting up streams, Scott addresses security configuration. This section is critical for production environments.
User Permissions
Scott navigates to Tools > Administration > Permissions. He points out that by default, the “remote” user has full access to everything, which he describes as “quite strange.”
His recommendation: “Use this line here to block every user from everything in all depots and then specifically enable specific users or groups as and when needed.”
Configurables for Security
Scott reviews several important server configurables:
- Security level should be set to at least 2 or 3 for strong passwords and ticket-based authentication. Scott warns that setting it to zero means “you don’t even need a password, which for a server that’s available on the internet, that is a very bad idea.”
- MinClient version should be set to prevent older P4V clients from connecting. Scott sets it to 2023.1, explaining that older versions “can be a performance hit as the server has to jump through hoops to support older versions.”
- Run.users should be set to “authorize” to prevent unauthenticated users from listing users on the server. Scott notes this prevents attackers from obtaining user lists for brute force attacks.
- dm.user.noautocreate prevents the server from automatically creating users when someone tries to access a nonexistent account. Scott emphasizes this is important when “you’re paying on a per license basis.”
- dm.password.minlength should be set to at least 8 characters, though Scott notes “you can go to 10 or 12 or 27 if you like.”
- dm.user.setinitialpassword ensures only super users can set initial passwords for new users.
- dm.user.resetpassword requires new users to change their initial password on first login.
- dm.info hides private information from the
p4 info
command. “The less information out there, the better,” Scott explains. - dm.user.hideinvalid prevents error messages on authentication failures to mitigate brute force attacks.
Multi-Factor Authentication Alternatives
Scott discusses multi-factor authentication for Perforce servers. While MFA plugins exist, he notes they require compilation and installing plugins from GitHub, which is “quite a pain to set up.”
His recommended alternative: “What is much easier is to install a VPN and a VPN with multi-factor authentication. So then you’re behind the VPN and the multi-factor authentication is built in at that point.”
Cloud providers can typically whitelist IP addresses or ranges. If developers work from the same office, IP whitelisting helps significantly. For distributed teams with dynamic IPs, VPNs provide a more practical solution.
Creating the Stream Structure
Scott creates a branching structure designed for managing multiple Unreal Engine versions and team development.
- Mainline Stream
First, he creates the mainline stream. This serves as the stable integration point where builds are generated. - Master Streams for Engine Versions
Scott creates a stream called “master UE 5.6” as a development branch under mainline. This stream holds the unmodified source from Epic Games for that specific engine version. - Development Streams
He creates personal development streams (dev/John, dev/Montana) where individual developers work on their changes. - Release Streams
Scott creates an alpha release stream as a release branch from mainline. This is where stable releases are tagged.
Planning for Future Engine Versions
For future engine upgrades, Scott demonstrates creating a “UE 5.7 merge” development branch from mainline, then a “master UE 5.7” branch underneath it.
He explains the workflow: “What will happen is the developer working on this will sync from mainline every day to get your latest changes that you’ve been working on in your company.” The developer copies up from the new engine master to the merge branch, works through all conflicts in the merge branch, and once everything works correctly, copies up to mainline.
This structure isolates the upgrade work and allows the team to continue mainline development without disruption.
Creating Workspaces and Adding Files
Scott creates a workspace mapped to the UE 5.6 master stream. He begins adding files to Perforce, starting with small root files to verify everything works correctly.
“As there are quarter of a million files here, adding them all in one changelist is very time consuming and should anything go wrong, you’ll have to start from scratch,” Scott explains. His approach is to add folders one at a time.
He submits the templates folder with 5,085 files as a test. For the demonstration, Scott skips the tedious process of adding every folder individually, but he recommends this approach for production setups.
Handling Text Encoding Issues
After adding all files, Scott runs “Reconcile Offline Work” to check for missing files. This reveals resource files in the Nvidia texture tools that have encoding problems.
“That’s the classic problem with UTF-16 getting confused with regular text files,” Scott says. “This has annoyed me in the past to the point where I actually made a utility to fix up and remove all UTF files from a repo.”
He runs a utility called “UTF-16 Must Die” (available on GitHub) to convert these files to UTF-8. The tool converts all UTF-16 files in the repository to proper UTF-8 text files that Perforce handles correctly.
Scott mentions that if developers want to understand why UTF-8 should always be used, they should visit utf8everywhere.org.
He reverts most of these conversions because the goal is keeping the master stream as similar as possible to Epic’s source. However, he notes that teams can optionally remove unnecessary localization files to save space.
Copying to Mainline
Once the UE 5.6 master stream is populated, Scott copies all files to the mainline stream. He creates a new workspace for mainline and uses the stream graph to copy files from the master to mainline.
The copy operation takes considerable time given the repository size.
Generating Project Files and Compiling
With files in mainline, Scott generates the Visual Studio project files. The generation completes successfully, though it doesn’t generate for all platforms since not all platform SDKs are installed. As long as Windows builds work, development can proceed.
Scott opens the generated solution in Visual Studio. The solution contains numerous projects representing different engine components.
Visual Studio indicates missing components for full development. Scott pauses the recording to install required NuGet packages and additional tools.
After updating dependencies and reverting unchanged files, Scott builds the Development Editor 64-bit target. The compilation finally completes successfully.
Creating Test Projects
Scott runs the Unreal Engine editor for the second time. He notes the first run spent significant time compiling shaders, which he skips for the demonstration.
He recommends creating two projects: “The main project you do production work in and a sandbox to play around in.”
To make the sandbox project appear in Visual Studio’s Solution Explorer, Scott explains a specific workflow: open the sandbox project in Unreal Engine, go to Tools > New Class, add a blank class (it doesn’t need functionality), then regenerate project files. This makes the project appear properly in the solution.
He sets the sandbox project as the startup project so pressing F5 runs it directly.
Making Engine Changes
Scott demonstrates making a sample change to engine code. He opens an audio editor source file and adds a comment with a specific format.
“Any change you make to the engine, I’d recommend you comment with your company name begin and then your initials,” Scott advises. He uses the format:
// ANDUIN-BEGIN JJS // Pointless comment // ANDUIN-END
This tagging system serves a critical purpose: “Whenever you’re upgrading to a new version, you can search for ANDUIN. It will have any changes you make and the person to talk to about why they made those changes.”
After making the change, Scott connects to Perforce, checks out the file, and submits it. The stream graph now shows that changes exist in the personal branch that need to be copied to mainline.
Q&A session
Branching Strategy for Engine Versions
A participant asks about the UE 5.7 merged stream and the branch underneath it.
Scott explains: “The 5.7 wants to be an unmodified master of UE 5.7 which has no changes whatsoever. So then you always have you can do a difference between the files in the 5.6 master to the 5.7 master to see what has changed.”
This structure maintains a source of truth for what Epic supplied versus the team’s working version. Montana follows up asking if this simplifies future upgrades, and Scott confirms: “Yes, it does. It keeps everything more contained.”
Scott elaborates that from experience, branching different engine versions can create significant confusion. “Having a source of truth for what is supplied from Epic versus your working version is a definite boon.”
Single Stream vs. Multiple Streams for Engine Versions
Another question asks about using a single stream and merging different Unreal Engine versions progressively instead of having separate streams for each version.
Scott responds that both approaches work. His method allows diffing between UE 5.6 and 5.7 directly rather than using history in a single master branch. “So up to you your preferred method of doing it.”
Montana suggests creating task streams as another option. Scott adds that having completely separate masters helps with debugging: “Sometimes it’s handy when you find a bug and did this bug exist in UE 5.6, did this bug exist in 5.7.”
Working Without Streams
A participant mentions their company has IT-controlled Perforce servers without streams enabled and asks for tips on branch flows without streams.
Scott’s short answer: “No. It’s been over a decade since I’ve actually done that. So I wouldn’t feel confident on commenting on that.”
Andre from Assembla provides more technical detail. He explains that migrating from depot to streams is non-trivial. If a Perforce server is IT-controlled and hasn’t been upgraded, it needs gradual updates to support modern features.
“When you create a branch you won’t be using too much storage” with streams, Andre explains. “But when you create a full copy of a depot as a branch it will be as large as the initial depot.”
Without streams, branching requires full depot copies, which consumes massive storage and makes branch management impractical. Andre notes that Assembla can assist with migrating older Perforce servers to versions supporting streams.
Repository Size
When asked how large the repository gets with UE5 and project files, Scott clarifies that project files aren’t shipped. “They’re generated on each client.”
For repository size, Scott mentions the largest Perforce depot he’s heard of is 56 terabytes. For the vanilla setup demonstrated, he asks Andre to check the actual size of the test server.
Andre confirms: “About 40 gigabytes.”
Scott notes that content drives repository growth. “As soon as you start generating assets, especially Nanite assets, then that is going to explode.”
Key Takeaways
Scott and Montana’s demonstration provides several critical insights for teams working with Unreal Engine 5 source:
- Hardware matters significantly. Without adequate CPU cores, RAM, and fast storage, source compilation becomes impractical for daily development.
- Security configuration is essential. Default Perforce settings are permissive and unsuitable for production environments. Proper user permissions, password policies, and access controls must be configured before adding production code.
- Stream structure enables scalability. Properly designed streams isolate engine versions, support parallel development, and simplify upgrades. The “merge down, copy up” workflow keeps mainline stable while allowing experimental work in isolated branches.
- Tagging engine modifications is critical. Consistent comment formatting identifying company and developer makes future engine upgrades manageable.
- Incremental file addition prevents problems. Adding quarter-million file repositories in single operations risks failure. Adding folders incrementally provides recovery points if issues occur.
- Text encoding matters. UTF-16 files cause problems with Perforce and build tools. Converting to UTF-8 prevents these issues.
For teams serious about Unreal Engine 5 source compilation, these workflows provide a foundation that scales from small teams to large studios. The next session in this series will cover CI/CD pipelines that understand game development realities.
Teams interested in single tenant Perforce instances managed by Assembla can visit getassembla.com or contact the team directly for assistance with setup and migration.