I'm working on a game called STEALGULLS. It's a co-op game where you and your friends play as annoying seagulls terrorizing beachgoers, stealing their food strategically or chaotically. You know, important work.
One of the things I wanted from the start was Mac support. A lot of my friends are on Mac (the Apple Silicon ones are actually pretty capable gaming machines now) and I didn't want to leave them out. But getting UE5 to build and run properly on Mac turned out to be... an adventure.
I'm writing this down because I spent way too long figuring some of this out and I'm hoping it saves someone else the pain. This is specifically for UE5.6 but maybe the fixes I mention below apply to later versions too.
Prerequisites
Before you do anything, make sure you have:
- Xcode 16+ installed and configured
- Xcode license accepted: run
sudo xcodebuild -license - Xcode first launch: run
sudo xcodebuild -runFirstLaunch
I won't go into detail about these because the setup is pretty standard. You DON'T need an Apple Developer account or anything like that (unless of course you are distributing outside of Steam)
The UBT Patches (This is the Fun Part)
So here's where things get interesting. Out of the box, UE 5.6 has a bug in the Mac toolchain that causes linker errors. Specifically, it generates malformed @loader_path entries that end with just . which the linker really doesn't like.
You need to patch MacToolChain.cs which is part of UnrealBuildTool (UBT), not the engine itself. This is actually fine to do even on an installed engine because UBT is just a C# project that you can rebuild separately without recompiling the entire engine.
File location: /Users/Shared/Epic Games/UE_5.6/Engine/Source/Programs/UnrealBuildTool/Platform/Mac/MacToolChain.cs
First, make it writable:
chmod u+w "/Users/Shared/Epic Games/UE_5.6/Engine/Source/Programs/UnrealBuildTool/Platform/Mac/MacToolChain.cs"
Patch 1: Around Lines 416-419
The original code adds an rpath without checking if it's valid. Wrap it with a guard:
string BundleRelativeDir = Utils.MakePathRelativeTo(BundleLibraryDir, ExeDir).Replace("\\", "/");
if (!BundleRelativeDir.EndsWith("."))
{
LinkArguments.Add("-rpath \"@loader_path/" + BundleRelativeDir + "\"");
}
Patch 2: Around Lines 792-796
Same issue, different location:
RPathEntry = UnstagedBundlePrefix + DestDir.MakeRelativeTo(ReferencingFile.Directory);
if (!RPathEntry.EndsWith("."))
{
LinkArguments.Add($"-rpath \"@loader_path/{RPathEntry}\"");
}
Rebuilding UBT
After making the patches, you need to rebuild UnrealBuildTool so the changes take effect:
dotnet build "/Users/Shared/Epic Games/UE_5.6/Engine/Source/Programs/UnrealBuildTool/UnrealBuildTool.csproj" -c Development
This rebuilds just UBT without touching the engine itself. Once that's done, your next project build will use the patched toolchain.
Important: These patches get blown away if you verify or repair the engine through Epic Games Launcher. You'll have to reapply them and rebuild UBT again. I learned this the hard way after wondering why my builds suddenly broke again.
Project Config
A few settings in your project config that you should set before building:
DefaultEngine.ini
[/Script/MacTargetPlatform.XcodeProjectSettings]
bUseSwiftUIMain=False
This disables SwiftUI main entry point. Swift 6 introduced some library requirements that cause linker errors if this is enabled. Just turn it off unless you specifically need SwiftUI (you probably don't for a desktop game).
Config/MacEngine.ini (Steam Overlay Fix)
This one drove me crazy. UE5 on Apple Silicon defaults to a 10-bit pixel format for the back buffer. Sounds fine, right? Well, it causes graphical corruption with the Steam overlay. The overlay renders but it's all garbled.
Add this to Config/MacEngine.ini:
[/Script/Engine.RendererSettings]
r.DefaultBackBufferPixelFormat=0
0 is 8-bit RGBA (works), 4 is 10-bit (broken with Steam).
Entitlements
Steam SDK doesn't play nice with Mac's App Sandbox. Your entitlements file needs to explicitly disable it and enable networking. Create or edit Build/Mac/Resources/Sandbox.Server.entitlements:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<false/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
</dict>
</plist>
UE reads this file during packaging automatically. Make sure Project Settings → Platforms → Mac points to Sandbox.Server.entitlements. No manual codesigning needed after the build.
The Build Commands
Clearing Out Old Stuff
As usual - clear your intermediates.
rm -rf Intermediate Binaries Saved/StagedBuilds
Building the Editor (Optional)
If you want to test in-editor first:
"/Users/Shared/Epic Games/UE_5.6/Engine/Build/BatchFiles/Mac/Build.sh" \
MyProject13Editor Mac Development \
"/PATH/TO/YOUR/PROJECT/MyProject13.uproject"
Packaging the Actual App
This is the main event. RunUAT handles the full cook and package:
"/Users/Shared/Epic Games/UE_5.6/Engine/Build/BatchFiles/RunUAT.command" \
BuildCookRun \
-project="/PATH/TO/YOUR/PROJECT/MyProject13.uproject" \
-platform=Mac \
-clientconfig=Development \
-build -cook -stage -package -archive \
-archivedirectory="/PATH/TO/YOUR/PROJECT/Builds" \
-pak -iostore -compressed
Your packaged app ends up at /PATH/TO/YOUR/PROJECT/Builds/Mac/MyProject13.app.
Steam Setup
If you're using Steam (which I am for multiplayer), you need to create steam_appid.txt in a specific location inside the app bundle:
echo "480" > "/PATH/TO/YOUR/PROJECT/Builds/Mac/MyProject13.app/Contents/UE/MyProject13/Binaries/Mac/steam_appid.txt"
The 480 is Valve's test App ID. Replace it with your actual Steam App ID for release builds.
Getting Steam Overlay to Work
Here's something that took me way too long to figure out: on Mac, the Steam overlay only works if you launch the game FROM Steam. If you don't have a Steam page yet or if you do have one but haven't spent all the time setting it up, you can still test the overlay by adding your game as a non-Steam game manually.
- Steam → Library → Add a Game → Add a Non-Steam Game
- Browse to your .app file
- Launch from Steam's library
If you just double-click the app directly, SteamAPI_Init() succeeds but the overlay never shows up. The game works fine otherwise which makes it extra confusing when you're trying to debug it.
Mac builds in Unreal are definitely more involved than Windows. There's the Xcode setup, the engine patches, the Steam quirks. But once you get it working, it actually runs pretty well on Apple Silicon. M1/M2/M3 Macs can handle a lot more than people give them credit for and having Mac support means more people can play your game which is kind of the whole point.
If you're also building a UE5 game and targeting Mac, hopefully this saves you some of the debugging I went through. And if you find better solutions to any of this, let me know. I'm always happy to update this with better approaches. Or if you have questions - find me on our Discord server!