Files
gen1recomp/mobile/ios
hernan 1e6f504a84 iOS picker: a "stadium" kind, and a way to ask which kinds exist
Two things, the second of which is the reason the first is safe.

A NEW KIND. pickFile("stadium") opens the document picker for a Nintendo 64
cartridge and lands it as picked_stadium.z64. The caller I wrote it for is
the Dramatic Shape voxel mod, which builds Pokemon Stadium battle models out
of the player's own cartridge -- on desktop it opens a dialog for that, and
on iOS it could only print a sandbox path to a screen and ask the player to
put a file somewhere they cannot reach from a phone.

Its own filename, not picked_rom.gb, because that is the name the Game Boy
importer watches: a 32 MB N64 ROM landing there is deleted and then reported
to the player as a broken cartridge.

WHICH IS ALSO WHAT AN UNKNOWN KIND USED TO DO. The switch's default case
treated anything it did not recognise as a Game Boy ROM, so a caller asking
for a kind the build predates lost the player's file -- the worst available
answer to "I have not heard of that one". Unknown kinds are refused now.

That refusal is invisible on its own: pickFile returns false, which is also
what "the picker would not open" returns, and a mod cannot tell them apart.
So the host says what it knows -- love.system.pickFileKinds() returns
"rom,mod,sav,stadium", or nil where there is no bridge. A caller asks first
and keeps whatever fallback it had; the voxel mod shows its folder note
again, which is what it did before any picker existed.

Tested on an iPhone 17 Pro: a Stadium cartridge imports from the picker and
the models build.
2026-08-07 22:13:50 -04:00
..

iOS build (LÖVE 12.0)

Native ROM/mod/save import. The iOS build ships a Swift document-picker bridge (native/GRPickerBridge.swift + GRBootstrap.m) that patch_love_src.py wires into the LÖVE tree on every build:

  • love.system.pickFile("rom"|"mod"|"sav") and love.system.createFile are exposed to Lua on iOS (same contract as love-android's SAF picker: picks land in the save dir as picked_rom.gb / picked_mod.zip / picked_save.sav; exports signal via export_done.flag).
  • The Info.plist overlay enables UIFileSharingEnabled + LSSupportsOpeningDocumentsInPlace, and GRBootstrap.m sweeps .gb/.gbc/.zip/.sav files dropped in Documents (Files app / Finder) into the LÖVE save dir on every activation — drop a ROM, open the app, and it imports with no taps.
  • src/import/RomImporter.lua treats iOS as a mobile platform and polls for picker results (iOS pickers are in-process modals, so Android's refocus rescan never fires).

The note below about a missing "UIDocumentPicker handoff" is resolved by this bridge.

macOS + Xcode only. Fetches the LÖVE 12.0 source tree and matching Apple dependencies from the official LÖVE source and Apple dependencies repositories. conf.lua declares LÖVE 12.0 on iOS and 11.5 elsewhere.

Pin file: LOVE_VERSION12.0.

Quick start (simulator)

# Fetch LÖVE 12.0 iOS sources and dependencies (once) + build for Simulator
scripts/build_ios.sh --fetch

The embedded game.love contains no ROM or generated game data. The current first-boot importer has desktop file pickers only, so a production iOS release still needs a UIDocumentPicker handoff that passes the selected ROM to LÖVE.

Default output: an unsigned Simulator .app under mobile/ios/build/ (no Apple Developer account required). A convenience copy also lands under dist/ios/<Config>-<sdk>/.

Install on a booted simulator (example):

xcrun simctl install booted mobile/ios/build/Build/Products/Debug-iphonesimulator/PokemonRed.app
xcrun simctl launch booted com.theboisclub.pokemonred

Or open mobile/ios/love-src/platform/xcode/love.xcodeproj in Xcode, select the love-ios target, and Run on a Simulator after scripts/build_ios.sh --package-only (or a full build) has placed game.love.

Device / Release

scripts/build_ios.sh --device            # Debug, physical device SDK
scripts/build_ios.sh --device --release  # Release configuration

Device builds need a signing identity and provisioning profile configured in Xcode (or via DEVELOPMENT_TEAM / CODE_SIGN_IDENTITY env vars). This repo does not store certificates, profiles, or App Store Connect secrets.

Manual out-of-band steps:

  1. Apple Developer account + App ID for com.theboisclub.pokemonred
  2. Development or Distribution certificate + provisioning profile
  3. In Xcode: open love.xcodeproj → target love-ios → Signing & Capabilities → select your Team (or set DEVELOPMENT_TEAM=XXXXXXXXXX when invoking scripts/build_ios.sh --device)
  4. Archive / export an .ipa from Xcode Organizer for TestFlight / Ad Hoc

Layout

Path Role
LOVE_VERSION Engine pin (12.0)
overlays/love-ios.plist Portrait-only Info.plist + display name Pokemon Red (copied over the upstream plist every build)
love-src/ Downloaded LÖVE 12.0 source tree (gitignored, do not commit)
cache/ Temporary source and dependency checkout data (gitignored)
build/ xcodebuild derived data (gitignored)

Game payload lands at:

love-src/platform/xcode/ios/resources/game.love

and is fused into the built .app (LÖVE auto-runs any bundled *.love).

Apple libraries dependency

scripts/build_ios.sh --fetch retrieves the matching iOS libraries and the SDL3 framework from love-apple-dependencies. Re-run it if either dependency directory is absent.

App identity

Field Value
Display name Pokemon Red
PRODUCT_NAME PokemonRed
Bundle ID com.theboisclub.pokemonred
Orientations Portrait only (UIInterfaceOrientationPortrait)

Overrides are applied by the build script (xcodebuild settings + plist overlay) so refreshing love-src/ does not lose branding.

Flags (scripts/build_ios.sh)

Flag Meaning
(default) Simulator, Debug, no signing
--fetch Fetch the LÖVE 12.0 source tree and Apple dependencies if love-src/ is missing
--device Build against iphoneos instead of iphonesimulator
--release Release configuration instead of Debug
--package-only Zip game.love + apply plist overlay; skip xcodebuild

Also: scripts/build.sh ios delegates here (--release is forwarded).

Preconditions

  • macOS (Darwin) with Xcode + xcodebuild on PATH
  • iOS platform installed in Xcode (Settings → Platforms). xcodebuild -showsdks should list iphonesimulator / iphoneos. A partial install can fail IB/xib compiles with iOS … Platform Not Installed even when the SDK name appears.
  • love-src/ present (--fetch)
  • iOS libraries under love-src/platform/xcode/ios/libraries/ and SDL3 under love-src/platform/xcode/shared/Frameworks/