Files
SashaGoncharov19 51d085e865 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.
2026-10-23 15:27:58 +04:00

35 lines
3.7 KiB
Markdown

# Steam-free single-player target
User-directed scope: exclude Steam integration; retain basic local gameplay. Steam matchmaking, cloud saves, achievements, rich presence, overlay and Steam networking are outside this port's target. The installed macOS game is not modified.
The current translated RNG library and iOS prototype contain no Steam imports or Steam dynamic dependency. `tools/build_rng.py` rejects Steam undefined symbols; `tools/package_ios.py` checks both imports and linked libraries before packaging.
## Original binary observations
REA Mach-O import inventory observed eleven direct Steam imports, including `SteamAPI_Init`, callbacks, shutdown and SteamInternal interface acquisition. Import coverage is not exhaustive, and virtual interface calls extend beyond these named imports.
Independent LLVM symbol inspection found `SteamContextInterface`, `SteamContext`, and `DummySteamContext`. REA/Hopper subsequently confirmed the factory disassembly and decompilation. The interface factory is at ARM64 VA `0x100267594` (`SteamContextInterface::createContext(bool, bool)`). Its observed branches are:
- Nonzero second argument (`w1`) selects an object referencing `DummySteamContext`'s vtable.
- With the second argument zero, bit zero of the first argument (`w0`) branches to a base-interface object at `0x100267640`, without entering the Steam initialization block.
- The other branch contains calls into the Steam path and constructs `SteamContext` if initialization succeeds.
Parameter names and caller-level meaning have not yet been established. These observations do not prove full game startup through either optional context. The correct integration point is the factory/interface boundary, not a blanket success-returning replacement for every Steam import.
REA also found that the Steam initialization stub has two observed callers: the factory and `GlobalContext::init` at `0x100161584`. The latter contains an **inlined** Steam initialization block beginning at `0x100161608`. Editing only the out-of-line factory would miss it. At `0x100161604`, startup branches on `GlobalContext::headlessMode`; headless startup constructs the base context without Steam. The graphical port must select local services independently of headless mode, while preserving graphical startup. Whole-function body ranges and complete indirect-reference classification are unavailable from Hopper's public API, so these observations are not a complete reachability proof.
## Retained REA evidence
Canonical bundle: `evidence/factorio-functions-final.json`, ARM64 slice SHA-256 `2cb4de127b50d54c6c5666acfef2263fae16d11a3361ad39353ecf8a66a4d9c7`.
- Factory dossier: `ev_4ebc9cbefaeb34d2e4f642c8cfa48d5035442aa80f6a438bf6481d215d1fe694`.
- Steam initialization stub/callers: `ev_c2713194813cae2a2677b7d73a284f9f99b4b9214e59f58cf8ee2a0ffc159f09`.
- Global startup dossier: `ev_7f2a2b88000ba82d85771c0f368eae9cf0a1f071beb7d73506ba6bbf3c0a22eb`.
- Base `isSteamApiInitialized()` assembly returns zero: `ev_0b47cba381075942160840ec0d392a8f05803c3c8a2ebb672bb01c4a282f4a5b`.
The interface includes cloud storage, locale, networking, callbacks, on-screen keyboard, stats and achievements. Local replacements must preserve actual method contracts and object layout once lifted callers use them. Returning invented success or a fake Steam identity would hide missing behavior; the port should expose unavailable optional services and use local file storage and native text entry.
## Remaining work
Replace the inlined startup integration when that engine function is lifted, audit optional-service checks, and prove no Steam-only branch is reachable from the chosen local startup. A full translated engine does not exist yet, so Steam exclusion has only been verified for the current prototype.