---
id: server-architecture/015
title: First iOS build — run the game on an iPhone from Kris's Mac
epic: server-architecture
state: done
priority: 2
blocked_by: []
estimate: S
created: 2026-08-13
updated: 2026-08-18
claimed_by: null
claimed_at: null
delivers: []
review_artifact: land-of-lor/game/export-ios.sh
---

## What

Kris's call, 2026-08-13: attempt the first-ever iOS build of the game, today,
on his Mac. This is hands-on-Mac work (agents in this workspace have no Mac),
so this task is the runbook plus the repo-side prep — the prep is already
done: an iOS export preset exists in `game/world/export_presets.cfg`
(land-of-lor `6350b1d` — bundle id `au.com.cocreations.lor-spellgrove` with
Kris's Team ID baked in; Android uses `lor_spellgrove` since Android forbids
hyphens in app ids; `export_project_only=true` so Xcode owns signing. The
"spellgrove" ids are a naming direction, still provisional — Kris, 2026-08-13).

The project should export clean: pure GDScript (no native plugins), all
network traffic is TLS (`wss://` to the live director — satisfies iOS App
Transport Security), and the mobile default director URL is already baked in.
Nobody has ever run this export, so expect small snags, not big ones.

## The Mac runbook

1. **Install Godot 4.7.1** — official universal .dmg from godotengine.org
   (must be 4.7.1 to match the project). Open it once, then
   Editor → Manage Export Templates → Download and Install (4.7.1.stable).
2. **Install Xcode** from the Mac App Store (large download). Launch once,
   accept the license, let it install the iOS platform. Then
   `xcode-select --install` for the command-line tools.
3. **Clone the repo** (private — needs GitHub auth on the Mac):
   `git clone git@github.com:krisrandall/land-of-lor.git`
4. **Open the project**: `land-of-lor/game/world/project.godot` in Godot.
   Let the import finish.
5. **Export**: Project → Export → the **iOS** preset → Export Project (it
   produces an Xcode project folder, e.g. under
   `game/world/client/ios-build/`). If Godot complains about missing icons,
   assign `client/ui/assets/lor-banner.jpg`-derived placeholders or let it
   use defaults — cosmetic only for a device build.
6. **Xcode**: open the generated `.xcodeproj`. Signing & Capabilities →
   Team → your personal team (a **free Apple ID is enough** to run on your
   own iPhone; the $99/yr Developer Program is only needed later for
   TestFlight / App Store / Game Center — see 010-accounts-plan.md's
   provider table).
7. **iPhone**: plug in via cable, trust the Mac, and enable Developer Mode
   (Settings → Privacy & Security → Developer Mode, then reboot — iOS 16+).
   Select the device in Xcode and Run.
8. **Sign in on the iPhone**: the account-first flow works cross-platform
   already — either create a new character, or attach the phone to your
   existing account with a typed **link code** from your Android/web session
   (Account → Add a device). QR scanning waits on 012's `PUBLIC_BASE_URL`.

## Definition of done

The game runs on a real iPhone against the live director: signup or
link-code attach, walk around the commons, see other players. Snags found
along the way get written back into this file (or a handoff) so the next
iOS build is a checklist, not an expedition. Game Center sign-in is NOT this
task (speced in 010's plan; needs the paid Developer Program — later).

## Done on device — 2026-08-13

Kris ran the game on his iPad Pro the same day: exported from Godot 4.7.1 on
the Mac, signed in Xcode (bundle `au.com.cocreations.lor-spellgrove`, Team
GUBJ3SLQ7S), launched against the live director. The session also produced
**`game/export-ios.sh`** (land-of-lor `b7de399`) — headless Godot export +
`xcodebuild` device build, with `--deploy` installing and launching on the
iPad — so the next iOS build is one command on the Mac, not an expedition.
Snags encountered and fixed along the way: the icon-set requirement (full
placeholder set now wired into the preset, `9f4d20b`) and Godot rewriting
`export_presets.cfg` wholesale on first open in 4.7.1 (accepted, committed).
In `review` for Kris's formal sign-off, per convention.