- README rewritten as a step-by-step guide for non-developers - install.sh: build, install and copy data with plain error messages - build_native.py: bundle identifier from the user's provisioning profile (Xcode project named factorio), version check on every build, friendly errors
6.9 KiB
Building, installing and running
All commands run from the repository root on the Mac. Nothing needs to be installed with pip; the scripts use only the Python standard library and Xcode's command-line tools.
1. Prepare the Mac
- Install Xcode from the App Store, open it once, and install the iOS platform when it asks (Xcode → Settings → Components).
- Sign into your Apple developer account: Xcode → Settings → Accounts.
- Install Factorio for macOS through Steam and let it finish downloading. The build expects
version 2.0.77; it checks the SHA-256 of the executable's ARM64 slice
(
2cb4de127b50d54c6c5666acfef2263fae16d11a3361ad39353ecf8a66a4d9c7) and stops if it differs. Turning off automatic Steam updates for the game keeps the build working until the port is updated for a newer version.
The default game location is
~/Library/Application Support/Steam/steamapps/common/Factorio/factorio.app/Contents. Pass
--game /path/to/factorio.app/Contents (or set FX_GAME) if yours is elsewhere.
2. Prepare the iPhone
-
Connect the iPhone by cable, unlock it and tap Trust for this Mac.
-
Enable Developer Mode: Settings → Privacy & Security → Developer Mode, then restart.
-
Check that the Mac sees it:
xcrun devicectl list devicesThe phone should be listed as
available (paired).
Signing
The app is signed with your Apple Development certificate and a development provisioning
profile from ~/Library/Developer/Xcode/UserData/Provisioning Profiles. The build chooses:
- with
--bundle-id(orFX_BUNDLE_ID): a profile for exactly that App ID, else a wildcard (TEAMID.*) profile; - otherwise: the newest profile whose App ID contains
factorio, and that App ID becomes the app's bundle identifier; - otherwise: a wildcard profile, with bundle identifier
local.factorio.native.
It signs with the keychain identity whose certificate is embedded in the chosen profile; the team
comes from the profile (override with --team / FX_TEAM). Expired profiles are ignored.
The README's step 4 creates a suitable profile: an empty Xcode iOS App project named factorio,
with automatic signing for your team, run once on the iPhone. Its App ID
(com.<you>.factorio) is unique to you, which Apple requires for explicit App IDs.
Free Apple accounts work the same way, but the installed app expires after seven days and has to
be reinstalled with ./install.sh (saves are kept). This has been tested with a paid account
only.
3. Build and install
./install.sh # same as: python3 tools/build_native.py --install --push-data
install.sh runs the steps below with short progress messages and writes the full output to
build/install.log. What happens:
- Inputs. The ARM64 slice of the game executable is extracted with
lipointobuild/factorio.arm64. The Wuffs PNG decoder source (v0.3.4) is downloaded intothird_party/wuffs/and checked against its pinned SHA-256. - Retarget.
tools/retarget.pywritesbuild/native/Factorio.dylib, changing only Mach-O header bytes, and records the changes inbuild/native/retarget.json. - Shims and host. The shim libraries and the small host executable are compiled for iOS with clang; the app icon is generated from the game's own icon.
- Bundle and sign.
build/native/Factorio.appis assembled, signed, and installed withdevicectl. - Data.
--push-datacopies the game'sdata/folder (~1.5 GB) into the app'sDocuments/factorio/dataon the phone. This is only needed the first time, after deleting the app, or after a game update.
The bundle never contains game data. Game settings, saves and logs are written to
Documents/factorio/ inside the app's container and survive reinstalls.
4. Run
Tap the Factorio icon on the home screen, or launch it from the Mac with the console attached:
python3 tools/build_native.py --no-build --launch
The phone must be unlocked for a launch from the Mac. Console output (the shim's [fx] lines and
Factorio's own log) is shown and saved to build/native/console.log. The first start after
installing takes the longest; the main menu normally appears after about 16 seconds.
Options
| Option | Environment | Default |
|---|---|---|
--game PATH |
FX_GAME |
Steam location (see above) |
--team ID |
FX_TEAM |
Taken from the provisioning profile |
--bundle-id ID |
FX_BUNDLE_ID |
From the provisioning profile (see Signing) |
--device ID |
FX_DEVICE |
First paired device |
--no-build |
Install/launch the existing bundle |
python3 tools/build_native.py --help prints the same list.
Rendering resolution
By default the game renders at the panel's native resolution. To render fewer pixels (for
battery or frame rate), put a divisor in Documents/factorio/render-divisor.txt on the phone,
for example 1.5, using Finder's file sharing for the app or devicectl device copy to. Valid
values are 1 to 4. Restart the app afterwards.
Copying saves
Saves are in Documents/factorio/write/saves/. With the phone connected, Finder shows the app's
files under the phone → Files → Factorio. A save from the Mac can be copied in the same way:
xcrun devicectl device copy to --device <id> --domain-type appDataContainer \
--domain-identifier <bundle identifier> \
--source ~/Library/Application\ Support/factorio/saves/my-save.zip \
--destination Documents/factorio/write/saves/my-save.zip
Troubleshooting
| Symptom | Cause and fix |
|---|---|
wrong Factorio version |
The installed game is not 2.0.77. Select that version in Steam (game Properties → Betas) or pass --game to a 2.0.77 install. |
no provisioning profile found |
See Signing. |
Unable to launch … because the device was not, or could not be, unlocked |
Unlock the phone and run the launch again. |
| App shows "Game data missing" | Run python3 tools/build_native.py --no-build --push-data. |
| App closes during play | Run with --launch, then python3 tools/symbolize_native.py to turn the [fx-crash] lines in build/native/console.log into function names. If there is no crash report, iOS may have stopped it for memory; check Settings → Privacy & Security → Analytics & Improvements → Analytics Data for a JetsamEvent report. |
| Image looks blurry | Check that render-divisor.txt is absent or contains 1. Text size is set separately with Factorio's UI scale. |
Diagnostics
python3 tools/native_audit.py build/factorio.arm64lists, per library, the game's imports that the iOS SDK does not provide. Every missing symbol must be implemented by a shim.python3 tools/symbolize_native.py [console.log]symbolizes crash reports using thefactorio.dSYMthat ships with the macOS game.tests/native/png_parity.mchecks the PNG decoder against macOS ImageIO for every PNG in the game data; the build command is in native-port.md.