Appearance
iOS
For: getting the game onto an iPhone or iPad, and from there onto the App Store.
What the iOS app is
The iOS app is an Expo application that wraps the web game in a native shell. It loads the deployed site in a web view. It adds the native pieces a browser cannot give: deep links, haptics, push notifications, a wake lock, offline and update-required screens, and back navigation.
That shape has a consequence worth holding onto. Shipping a change to the game itself is a web deploy, not an App Store submission. A new binary is needed only when the native shell changes.
The project lives under platforms/mobile, and its configuration is platforms/mobile/app.config.ts.
Identity
These values are committed and are the same on both platforms. Changing the bundle identifier after a store release starts a new app rather than updating the existing one.
| Item | Value |
|---|---|
| Display name | Grafted Wars |
| Bundle identifier | com.graftedwars.game |
| Expo slug | grafted-wars |
| Expo account | evgeniiarts |
| URL scheme | graftedwars |
| Version | 1.0.0, with build numbers held remotely by Expo |
| Orientation | portrait |
| Tablet support | on |
Encryption is declared as non-exempt in the configuration, which is what lets a submission skip the export-compliance questionnaire.
Once per machine
Install the mobile project's own dependencies, which are separate from the repository root's:
bash
npm ci --prefix platforms/mobileBuilding locally for a device also needs Xcode and a CocoaPods install, both on macOS. Building through Expo's hosted builders needs neither, which is the route the committed build script uses.
Which server the app talks to
The shell points at the production site by default. Override it to aim at staging or at a local loop:
bash
GRAFTED_WARS_GAME_URL=https://<staging address> npm run build:ios --prefix platforms/mobileThe value is validated rather than trusted. A URL carrying embedded credentials is discarded, and a plain-HTTP URL is discarded unless it is localhost and GRAFTED_WARS_ALLOW_HTTP_LOCALHOST is set to true.
Run it on a device or simulator
Start the development server and open the project:
bash
npm run start --prefix platforms/mobileTo build and run a native debug build on a connected device, on macOS:
bash
npm run ios --prefix platforms/mobileBuild for distribution
The committed script builds an internal-distribution build through Expo's hosted builders:
bash
npm run build:ios --prefix platforms/mobileThat uses the preview profile, which distributes internally and does not target the simulator. Three profiles exist in platforms/mobile/eas.json.
| Profile | Distribution | For |
|---|---|---|
development | internal, with the development client | day-to-day work against a dev server |
preview | internal | handing a build to a tester or to yourself |
production | store | an App Store submission, with the build number incremented automatically |
For a store build, name the production profile explicitly:
bash
npx eas build --platform ios --profile productionCredentials
Expo generates and holds the signing material, and prompts for what it needs on the first build. An Apple Developer Program membership is the prerequisite.
| Item | Where it comes from |
|---|---|
| Apple Developer Program membership | developer.apple.com |
| Distribution certificate and provisioning profile | generated and stored by Expo, backed by your Apple account |
| App Store Connect API key | appstoreconnect.apple.com → Users and Access → Integrations |
| Expo access token | expo.dev → Account Settings → Access Tokens, for non-interactive builds |
None of these belong in this repository. Credentials and access is the index.
App Store submission
Once a production build finishes, submit it:
bash
npx eas submit --platform ios --profile productionThe submission profile is present in the configuration and carries no options of its own, so the interactive prompts decide the target. Expect the App Store Connect listing, screenshots and review notes to be filled in through the web console rather than from here.
Prove it before you ship
Type-check the mobile project from the repository root:
bash
npm run mobile:typecheckThe project also carries its own suite, run from its own directory:
bash
npm test --prefix platforms/mobileSharp edges
A web deploy changes what every installed app shows, because the shell loads the live site. A bad production deploy therefore reaches phones without any store involvement.
The app images are generated rather than hand-drawn, and a check verifies they match. Run npm run images:check --prefix platforms/mobile when an icon or splash asset changes.
Build numbers are held remotely by Expo rather than in the repository, so two machines cannot disagree about the next one.