Native iPhone port of Factorio 2.0.77
Run the original macOS ARM64 game code on iOS: - tools/retarget.py: header-only Mach-O retargeting to an iOS dylib - platform/native: UIKit host and macOS API shims (AppKit for SDL's Cocoa backend, CoreGraphics displays, CoreAudio device, Metal device properties, Wuffs PNG decoding, Steam and peripheral stubs) - touch, overlay, iOS keyboard and hardware keyboard input - tools/build_native.py: build, sign, install, data copy, launch - docs: build guide, controls, architecture Also includes the earlier static-translation research (ARM64 -> WASM -> native) under docs/research, runtime/, tests/ and tools/. No game files are included; the build reads them from a local install.
This commit is contained in:
commit
51d085e865
89 files changed
+7999
No files matched your search
@@ -0,0 +1,136 @@
|
||||
# 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
|
||||
|
||||
1. Install **Xcode** from the App Store, open it once, and install the **iOS** platform when it
|
||||
asks (Xcode → Settings → Components).
|
||||
2. Sign into your Apple developer account: Xcode → Settings → Accounts.
|
||||
3. 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
|
||||
|
||||
1. Connect the iPhone by cable, unlock it and tap **Trust** for this Mac.
|
||||
2. Enable **Developer Mode**: Settings → Privacy & Security → Developer Mode, then restart.
|
||||
3. Check that the Mac sees it:
|
||||
|
||||
```sh
|
||||
xcrun devicectl list devices
|
||||
```
|
||||
|
||||
The phone should be listed as `available (paired)`.
|
||||
|
||||
## Signing
|
||||
|
||||
The app is signed with your **Apple Development** certificate and a development provisioning
|
||||
profile. The build script picks them automatically:
|
||||
|
||||
- it looks in `~/Library/Developer/Xcode/UserData/Provisioning Profiles` for a profile whose
|
||||
App ID is exactly the app's bundle identifier, or a wildcard (`TEAMID.*`) profile;
|
||||
- it signs with the keychain identity whose certificate is embedded in that profile;
|
||||
- the team ID comes from the profile (override with `--team` / `FX_TEAM`).
|
||||
|
||||
If you have no suitable profile yet, let Xcode create one: create any new iOS App project, set
|
||||
its bundle identifier to `local.factorio.native` (or your own identifier, then pass the same one
|
||||
to `--bundle-id`), choose your team under *Signing & Capabilities* with automatic signing, select
|
||||
your iPhone and build it once. Xcode then downloads a profile that the script can use.
|
||||
|
||||
Free Apple accounts can sign apps for their own devices, but the installed app expires after
|
||||
seven days and has to be reinstalled. This has only been tested with a paid account.
|
||||
|
||||
## 3. Build and install
|
||||
|
||||
```sh
|
||||
python3 tools/build_native.py --install --push-data
|
||||
```
|
||||
|
||||
What happens:
|
||||
|
||||
1. **Inputs.** The ARM64 slice of the game executable is extracted with `lipo` into
|
||||
`build/factorio.arm64`. The Wuffs PNG decoder source (v0.3.4) is downloaded into
|
||||
`third_party/wuffs/` and checked against its pinned SHA-256.
|
||||
2. **Retarget.** `tools/retarget.py` writes `build/native/Factorio.dylib`, changing only Mach-O
|
||||
header bytes, and records the changes in `build/native/retarget.json`.
|
||||
3. **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.
|
||||
4. **Bundle and sign.** `build/native/Factorio.app` is assembled, signed, and installed with
|
||||
`devicectl`.
|
||||
5. **Data.** `--push-data` copies the game's `data/` folder (~1.5 GB) into the app's
|
||||
`Documents/factorio/data` on 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:
|
||||
|
||||
```sh
|
||||
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` | `local.factorio.native` |
|
||||
| `--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:
|
||||
|
||||
```sh
|
||||
xcrun devicectl device copy to --device <id> --domain-type appDataContainer \
|
||||
--domain-identifier local.factorio.native \
|
||||
--source ~/Library/Application\ Support/factorio/saves/my-save.zip \
|
||||
--destination Documents/factorio/write/saves/my-save.zip
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Cause and fix |
|
||||
| --- | --- |
|
||||
| `unexpected input …; only the inspected 2.0.77 ARM64 slice is supported` | The installed game is a different version. Install 2.0.77, or delete `build/factorio.arm64` if it was extracted from another install. |
|
||||
| `no provisioning profile covers …` | See [Signing](#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.arm64` lists, 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 the
|
||||
`factorio.dSYM` that ships with the macOS game.
|
||||
- `tests/native/png_parity.m` checks the PNG decoder against macOS ImageIO for every PNG in the
|
||||
game data; the build command is in [native-port.md](native-port.md#verification).
|
||||
Reference in new issue
Block a user