Introduction
First of all, the keywords here are offline (or as offline as possible) and C++. So if these are not your concerns, then you can ignore this post. My project uses C++ and Blueprint, so I have to compile the project very often. This is normally not the case with Blueprint projects, but there are always times when you will have no choice other than using C++ due to the limitations of what you can do with Blueprint.
I have a limited internet quota per month, and it is very expensive compared to my income, so I have to be very conservative about it. To give you an idea of how limited it is, by just reinstalling Unreal 5.6 and Visual Studio and doing troubleshooting for a day, I used up 78% of my traffic in one day, and I still have 27 more days until the quota resets. This makes it very important for me to ensure my environment does not download stuff from the internet as much as possible, especially when that data already exists on my local PC (or network). This information is mostly observation and speculation, which is why this isn’t a tutorial in Learning but rather a forum post. Don’t trust it 100%, and if you have a different suggestion or correction, please comment below.
Preparation
During installation, if you have enough space on your OS drive (normally C), then go ahead and install everything in its default path. My OS drive is just 100GB, and it is already 70GB used, so I used a different drive (a network drive with about 68TB available space).
The Unreal folder structure that I will be using is as follows. This structure is suggested in Setting up an Unreal Engine Studio the Epic Way:
Unreal
UE_5.6
UE_5.7
VaultCache
QuixelCache
Zen5.6Cache
Zen5.7Cache
Project1
Project2
...
-
Download and install Epic Launcher if you haven’t already. Don’t use the installer that comes with Visual Studio; it will download it again at least twice since it is very outdated. Open %LocalAppData%\EpicGamesLauncher\Saved\Config\WindowsEditor\GameUserSettings.ini and change all the references to your OS drive to your install location (DefaultAppInstallLocation, VaultCacheDirectories and CreatedProjectPaths).
-
Install Unreal Engine in the default location, or choose a different drive and folder. I created a folder named Unreal at the root of the drive, then installed the engine under that folder as UE_5.6 (installing version 5.6). The shortest possible paths with no spaces in them are important. My installation becomes F:\Unreal\UE_5.6. Do not run it yet; we need some modifications.
-
Zip and back up the installation. You might need to restore it many times, and it will be a nightmare if you want to verify it each time. It downloads about 3~5GB, each time you verify it. Alternatively, add the entire UE5.6 folder to a separate source control repository so you can track modified, created, or removed files. If you are using zip backups, I suggest compressing each folder separately so the zip files are smaller and decompression is faster. I compressed each folder in UE5.6\Engine separately, and so on (it is about 30GB).
-
When you create a C++ project, Unreal places a .vsconfig file in the root of that project. In normal cases, you can delete it. It is used to configure the installation of Visual Studio. If you already have Visual Studio installed, you can run vs_setup --config .vsconfig to ensure you have all the necessary components. If you are doing a fresh install, I suggest creating an offline layout and using that to install Visual Studio. The installer tends to use a huge amount of data, ignoring installed or local packages and downloading them from the internet every single time.
To create a layout, create a folder called VSInstall in the root of your drive (you will rename this folder later). Download the installer from the Visual Studio website and copy it into that folder. Copy the .vsconfig file to this folder or create it with the following content (it is for Unreal version 5.6):
{
"version": "1.0",
"components": [
"Component.Unreal.Debugger",
"Component.Unreal.Ide",
"Microsoft.Net.Component.4.6.2.TargetingPack",
"Microsoft.VisualStudio.Component.VC.14.38.17.8.ATL",
"Microsoft.VisualStudio.Component.VC.14.38.17.8.x86.x64",
"Microsoft.VisualStudio.Component.VC.Llvm.Clang",
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"Microsoft.VisualStudio.Component.Windows11SDK.22621",
"Microsoft.VisualStudio.Workload.CoreEditor",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NativeDesktop",
"Microsoft.VisualStudio.Workload.NativeGame"
]
}
- Create a batch file named
download.bat with the following lines. You can change the language if needed. This will create an offline layout in the current folder using .vsconfig data. While running it, note the version number (mine was 2022 17.14.31). Note that vs_setup was the name of the installer I downloaded; yours might be different.
vs_setup --layout . --lang en-US --config .vsconfig
pause
- Now run the batch file and wait for it to complete. Once done, you will have a folder with about 1200 folders with very long names and 11–16GB of data. After completion, I suggest renaming the folder to
VS 2022 Installer 17.14.31 (use your own version number).
Create a new batch file called fix.bat in the same folder with the following content. I’m not sure if it still needs the --config switch, but I included it anyway. You will not run download.bat again, but instead run fix.bat. Running download.bat will download updated Visual Studio packages; running fix.bat will only verify the downloaded version and re-download corrupted packages if necessary. Just like Unreal, it will always download some files again, considering them corrupted even if they were just downloaded.
vs_Professional --layout . --lang en-US --config .vsconfig --fix
pause
- Create another batch file in that folder named
install.bat with the following content. This will automatically select the components and run with internet access cut off. It will still contact Microsoft but will not download packages from the internet and will fail if a required package does not exist in the offline layout. Without --noWeb, I noticed it ignores local data and downloads most of them again.
vs_setup --config .vsconfig --noWeb
pause
- Install Visual Studio, but do not run it yet; we will modify it slightly.
For the next steps, I’ll be using folder paths from my installation; please adjust them as needed.
Modifying Visual Studio
- From the Unreal Engine folder
F:\Unreal\UE_5.6\Engine\Extras\UnrealVS, run the UnrealVS.vsix file. It should install into Visual Studio and give you a new Unreal toolbar.
- Create a folder in the root of your
F drive called NuGetLib. This will be used as a cache for your downloaded libraries. From Tools -> Options, open the NuGet section and add a new library by clicking the plus icon, editing its name and source, and then pressing update. Use F:\NuGetLib as the source. The reason we are doing this is to have an extra library location that contains only Unreal-related packages. This will become important when working on other projects. The folder will remain empty for now. Do not disable the online NuGet source yet, or everything will stop working.
Modifying Unreal
Disable Zen
This step will save you a lot of trouble. Even though Epic is proud of Zen, it is still underdeveloped, rigid, and causes issues, especially in a single-developer environment where Zen storage is on the same drive as your project.
Open F:\Unreal\UE_5.6\Engine\Config\BaseEngine.ini. Under the [Zen] group, find AutoLaunch and set it to false. Under [Zen.AutoLaunch], change DataPath= from %ENGINEVERSIONAGNOSTICINSTALLEDUSERDIR% to F:/Unreal/Zen5.6Cache. This ensures Zen does not fill your OS drive with data.
Since we are using an installed version, modify the [InstalledDerivedDataBackendGraph] group so the engine doesn’t use Zen. (For compiled versions, use [DerivedDataBackendGraph] instead.) Replace everything under that group with the following:
Root=(Type=Hierarchical, Inner=EnginePak, Inner=CompressedPak, Inner=Pak, Inner=Local)
EnginePak=(Type=ReadPak, Filename=%ENGINEDIR%DerivedDataCache/Compressed.ddp, Compressed=true)
CompressedPak=(Type=ReadPak, Filename="%GAMEDIR%DerivedDataCache/Compressed.ddp", Compressed=true)
Pak=(Type=ReadPak, Filename="%GAMEDIR%DerivedDataCache/DDC.ddp")
Local=(Type=FileSystem, UnusedFileAge=34, PromptIfMissing=true, Path=%GAMEDIR%DerivedDataCache\Local, EnvPathOverride=UE-LocalDataCachePath, EditorOverrideSetting=LocalDerivedDataCache, CommandLineOverride=LocalDataCachePath)
This tells the engine to use EnginePak, CompressedPak, or Pak, and if data is not found, use Local. As mentioned earlier, the DDC cache does not guarantee order of use (horrible design) and will still copy data to Local (\facepalm). At least this way we know where the data is stored and can delete it if needed.
For GameDir, we need two DDC files; you will realize this later in a very painful way. The UE-LocalDataCachePath, LocalDerivedDataCache, and LocalDataCachePath allow changing the location of local data via environment variables, Editor -> Project Settings, and the command line (it is not DDC=). You can read about it here: Derived Data Cache (DDC).
%GAMEDIR% and %ENGINEDIR% refer to the project folder and engine folder.
Note: you need to use forward slashes instead of backslashes for paths, even if you are on Windows. I’m not sure if this is still required, but it helps avoid surprises later.
Save the BaseEngine.ini file and make two backups: one in the same folder and one outside. I used BaseEngine.mine.ini as an in-place backup in the same folder and BaseEngine.5.6.mine.ini outside the engine folder. When you verify or modify the engine, this file is always overwritten. Also have the original handy in case you mess up the content and need to start over.
Create C++ Project
To make sure everything works, we will create an empty C++ project. With your next project, you can add any content or use any template using this same method.
Problems start here. If you have limited internet, then everything will start failing from this point on. Once Visual Studio opens, it automatically wants to restore packages from the internet. You cannot restore packages from the NuGet Console or the Restore NuGet Packages menu item by right-clicking on the solution node in Project Explorer; they will all fail silently, making you think they did what they were supposed to do. If you haven’t had limited internet issues yet, you have probably already downloaded gigabytes of data.
So what do we need to do? If this is your first project, you have no choice, you will need to enable internet access and let NuGet do its work. However, for the second project and onward, you will be able to rely on content from your local NuGet library. For later project dependencies, you can download them manually and place them in your local library, or temporarily allow internet access and let NuGet download them for you.
Make sure %userprofile%\.nuget is empty. Don’t delete its contents, you might need them; just move them to another folder. This is important to separate packages needed by Unreal and your other projects.
Open Unreal Editor and create a project by selecting the Games category, choosing Blank as shown below, and then clicking Create. It will take some time, open a few dialogs, and appear to be doing important work. Then Visual Studio will open, and the editor will continue compiling shaders. This might take between 2–20 minutes depending on drive space, CPU, memory, and your graphics card.
Once Visual Studio starts automatically, it will immediately run NuGet and start downloading packages. Let it do so if this is your first project. There are about 57 projects in your solution, and each has its own NuGet packages that need to be restored. You will see their names in the output log of Visual Studio. Let it download what it needs. Once NuGet finishes downloading, close Visual Studio and wait for Unreal Editor to open.
Make the following changes to your project.
- In Unreal Editor, create an empty level and save it. Then open
Edit -> Project Settings, and under Project -> Maps & Modes, set the Editor Startup Map and Game Default Map to this empty level. This will ensure you can open the project faster; we will need to do this a few times. Close the Unreal Editor as well.
- While in Project Settings, navigate to
Project -> Supported Platforms and uncheck the All Platforms checkbox, then uncheck any platform that you will not be publishing on. I need to remind you that setting goals bigger than you can handle is guaranteed failure, so keep your goals realistic. Since I’m an indie dev, a single developer working on my project on weekends, and do not have the ability to support my game on more than one platform even if I wanted to, I disabled everything except Windows. I wasn’t able to compile automation for VisionOS anyway, so I had to disable it as well.
To make the editor load a little faster, you can disable any plugins that you will not be using, such as plugins under the Programming group, including 10x Editor, CLion, CodeLite, Xcode, VSCode, Rider, etc.
- Create a file called
Directory.Build.props in the root of your project with the following content. It will tell your project not to treat warnings as errors; otherwise, nothing will compile. Automation tools use some vulnerable packages, and they won’t compile unless you make this change. As far as I understand, these tools are not shipped with your final product, so you don’t need to worry about them yet. I tried upgrading these affected packages to the latest version, but the number of compile errors I got was much more than I could handle. I’ll leave it to Epic staff to fix.
<Project>
<PropertyGroup>
<NuGetAudit>false</NuGetAudit>
</PropertyGroup>
</Project>
- Open
F:\Unreal\TestProject\Config\DefaultEngine.ini, go to the end, and add the following lines. These will stop the EOS system from flooding the Unreal Editor log with messages that run every 2 seconds and add between 6–15 lines of log output. I’m not sure if this will disable the EOS subsystem as well (Epic Online Subsystem), but it will definitely disable the logging. If you need EOS, it is probably better not to add the first 5 lines and only disable logging.
[OnlineSubsystem]
DefaultPlatformService=Null
bHasEOS=false
[OnlineSubsystemEOS]
bEnabled=false
[Core.Log]
LogEOSSDK=NoLogging
LogEOSAuth=NoLogging
LogEOSOverlay=NoLogging
-
In the root of your project, create a Plugins folder, and inside it, create a VisualStudioTools folder. Copy/extract/clone vc-ue-extensions into that folder. The README.md should be located at F:\Unreal\TestProject1\Plugins\VisualStudioTools\README.md. If it is not, fix the issue; otherwise, neither Visual Studio nor Unreal will be able to find it.
-
Open Unreal Editor. It should show a dialog telling you that it needs to compile the VisualStudioTools; press Yes. Once the Editor window opens, close it again.
-
From the root of your project, open the Visual Studio solution (F:\Unreal\TestProject\TestProject.sln). You will also see the Unreal Engine Integration Configuration. In the first row, click the Refresh icon in front of the overall status. If you have installed VisualStudioTools as mentioned in step 5, then this is what you will see, and you just need to enable it. If not, you will see an Install button, which will silently fail (either during download or installation), and you will only see a red icon in that row that cannot be disabled or fixed, meaning you are probably stuck.
Enable the integration tool. Click on the Add and Configure buttons in the last two rows; this will open a save dialog. You don’t need to enter anything, just click Save, and it will create two files in the root of your project (.editorconfig and shadertoolsconfig.json). Click the Refresh icon on the Overall Configuration Status row at the top, and all the icons should turn green.
If you don’t see the HLSL tool installed, you need to modify your Visual Studio installation to install the HLSL debugger as well. Once everything is green, uncheck the box at the top that says Show on startup. You can always access this page from Project -> Configure Tools for Unreal Engine.
From Visual Studio, build the project.
-
Open Unreal Editor. It should show a dialog, telling you, it need to compile the VisualStudioTools, press Yes. Once Editor Window Opened, close it again.
-
From root of your project open the visual studio solution (F:\Unreal\TestProject \TestProject.sln). You will also see the Unreal Engine Integration Configuration. In first row click on Refresh icon in front of overall status.
If you have installed VisualStudioTools the way mentioned in 4, then this is what you will see and just need to enable it. if not, you will be seeing a install button which will silently fails (either during download or install) and you will only see a red icon in that row that cannot be disabled or fixed and you are probably stuck! Enable Integration tool, Click on Add and configure buttons and last two rows, which will open a save dialog, don’t need to enter anything, just click save and they will create 2 files in root of your project (.editorconfig and shadertoolsconfig.json).
Click on Refresh icon on Overal Configuration Status row on top and all the icons should go green. In case you don’t see the HLSL tool Installed, you need to modify your visual studio installation to install HLSL debugger too.
Once everything is green, uncheck the box on top that says Show on startup. you can always access this page from Project -> Configure Tools for Unreal Engine
From Visual Studio, build the project.
-
Once build succeed, move content of %userprofile%\.nuget\packages to your F:\NuGetLib. This will allow using them without connecting to internet. You might want to disable nuget online too, but you will need to enable it again when you are adding new packages to your project or manually copying them to your library.
TroubleShooting
- If the build does not succeed and, like me, you are getting the
'IOSPlatform' is inaccessible due to its protection level error, you can probably try to fix it, but you will run into other errors and a rabbit hole. The easiest solution is to disable VisionOS automation (which also disables publishing to VisionOS).
- Open
F:\Unreal\UE_5.6\Engine and create a folder called Platforms.Disabled. From the Platforms folder, move the entire VisionOS folder into Platforms.Disabled.
Next, from F:\Unreal\UE_5.6\Engine\Intermediate\ScriptModules, rename VisionOS.Automation.json to VisionOS.Automation.json.bak. Then open Unreal Editor; it will probably inform you that the source code is outdated. Press Update, or from the Tools menu select Refresh Visual Studio Project.
- If Unreal Editor is running, building from Visual Studio will almost always fail. Before building, close Unreal Editor first. Alternatively, you can use
Live Coding with Ctrl+Alt+F11, which updates the Visual Studio files and rebuilds the project.
- To verify whether your SDK is installed correctly, click Refresh Platform Status from the platform toolbar item, then open it again. Under your specific platform (mine is Windows), at the bottom you should see a gray message saying the platform is OK (otherwise it will show an error there).
- I noticed my copy of
F:\Unreal\UE_5.6\Engine\Source\ folder is readonly, which would cause random completely unrelated errors with vague messages. It might help to Right click on the folder, select properties, then uncheck readonly and click ok, next select apply to all folder content and press ok.
Final Thoughts
- Make sure your project is in version control and commit at least twice on a working day. Don’t use the same drive for version control. This will be a time saver in troubleshooting accidental changes, often caused by adding an asset to the project.
- I once had to troubleshoot a
PostProcessVolume that went completely dark, and nothing I tried would fix it. Even deleting and adding a new one wouldn’t fix it, and the problem wasn’t with it at all but with a setting in the project file, which I could easily find by tracking changes in version control.
- When Building a C++ project, the files in
Engine\Source folder are modified, if you get into a case that for no reason compile doesn’t succeed, restore that folder from your backup.