Files
Arcade85/AGENTS.md
T

150 lines
6.4 KiB
Markdown

# Arcade85
A 5-in-1 iOS collection of faithful **HD remakes** of five classic TI-85 calculator
games. Native **SwiftUI + SpriteKit**, one shared shell, each game a
`Scene` (SpriteKit) + `Sim` (pure Swift engine) pair.
This file is the operational runbook for an agent building/deploying Arcade85 on the
Mac Studio **without the human in the loop**. Read it top to bottom before touching
signing, git, or the build. It follows the same pattern as `~/dev/KyleCode/AGENTS.md`
(same Gitea, same `~/dev/.env` token, same signing identity).
---
## 1. Repo layout
```
Arcade85/
Arcade85.xcodeproj/ # hand-maintained (NOT xcodegen) — edit via Xcode/pbxproj
Arcade85/
Arcade85App.swift # @main
Shell/ # app chrome: RootView, GameHostView, GameCatalog,
# Theme, Haptics, HighScoreStore
Games/
SceneArt.swift # shared procedural texture/sprite helpers
DopeWars/ DopeWarsScene.swift + DopeWarsSim.swift
Lander/ LanderScene.swift + LanderSim.swift
Phoenix/ PhoenixScene.swift + PhoenixSim.swift + PhoenixData.swift
ZTetris/ TetrisScene.swift + TetrisSim.swift
ZMercury/ MercuryScene.swift + MercurySim.swift + MercuryData.swift
Galaxian/ (ported, dormant — see GameCatalog note)
ComingSoonScene.swift
README.md
```
**Convention:** every game is a `*Scene.swift` (SpriteKit, all UI/input) paired with a
`*Sim.swift` (pure Swift state machine — no UIKit/SpriteKit imports). The Sim is the
engine and is where mechanics live; the Scene only renders and routes touches. Keep
them separate. Dope Wars' `DopeWarsSim` is the reference for a well-factored Sim
(seeded RNG, a separate `extRng` stream for non-classic extensions, `#if DEBUG` debug
hooks, a `messages: [String]` queue the Scene drains one-per-tap).
The original TI-85 sources this was remade from live in sibling folders under
`~/dev/TI/` (`lander/`, `zetris/`, `phx4.0ti85/`, `zmercury-ti85/`, `galaxian-ti85/`).
They are **not** part of this repo.
## 2. Signing
- **Team:** `TG8X9PP8VT` (Kyle Albanese). **Identity:** "Apple Development: Kyle
Albanese (5SRT78F8BG)". **Bundle ID:** `com.albanese.arcade85`.
- **Automatic signing** (`CODE_SIGN_STYLE = Automatic`), `GENERATE_INFOPLIST_FILE = YES`
(no Info.plist file exists — don't add one).
- The current pbxproj does **not** pin `DEVELOPMENT_TEAM`; the identity in the login
keychain is used. If a device build ever fails to sign, set
`DEVELOPMENT_TEAM = TG8X9PP8VT` on the target (don't switch to manual profiles).
### Environment prerequisites (why this works)
Commands run as the user's **own launchd job in `gui/501` (Aqua session)**, so the
login keychain is readable by `xcodebuild`/`codesign`. Verify before a device build
(do NOT change anything if it fails — stop and tell the user):
```bash
launchctl managername # must print: Aqua
security find-identity -v -p codesigning /Users/fung/Library/Keychains/login.keychain-db
# must list: "Apple Development: Kyle Albanese (5SRT78F8BG)"
```
**Hard rules:** never revoke/recreate the Apple Development cert, don't touch keychain
settings, keep automatic signing, never commit `*.p8` or `*.env` secrets.
## 3. Build
Run from `/Users/fung/dev/TI/Arcade85`.
### Simulator (no signing — default for quick checks)
```bash
xcodebuild -project Arcade85.xcodeproj -scheme Arcade85 \
-destination 'generic/platform=iOS Simulator' -configuration Debug \
-derivedDataPath build/dd build CODE_SIGNING_ALLOWED=NO
```
Success: `** BUILD SUCCEEDED **`. (Verified 2026-09-16.)
### Device (real iPhone, auto-signed)
```bash
xcodebuild -project Arcade85.xcodeproj -scheme Arcade85 \
-destination 'generic/platform=iOS' -derivedDataPath build/dd \
-allowProvisioningUpdates build
```
Install/launch a paired device (list with `xcrun devicectl list devices`):
```bash
APP=build/dd/Build/Products/Debug-iphoneos/Arcade85.app
xcrun devicectl device install app --device <UDID> "$APP"
xcrun devicectl device process launch --device <UDID> com.albanese.arcade85
```
**There are no automated tests in this project.** A passing build is the check. For
gameplay, run in the simulator and play, or use the Dope Wars debug env vars below.
### Dope Wars debug env vars (DEBUG builds only)
`DopeWarsScene.didMove(to:)` reads `ProcessInfo` env vars for screenshot/demo poses:
`ARCADE_AUTOPLAY=1` (auto-start a run), `ARCADE_DEMO=1` (deterministic day-12 demo),
`ARCADE_DEMO_VIEW=buy|chase|tier3|over|ride|keypad|sharkchase|endless`. The
`DopeWarsSim` also exposes `debug*` mutators (wallet, debt, price, tier, held, forced
RNG rolls) gated behind `#if DEBUG`.
## 4. Git & Gitea
Remote: Gitea `https://git.kwalb.com/kyle/Arcade85` (branch `main`). No git
credentials in the keychain — use the API token from `~/dev/.env` inline, and let the
credential prompt fail to store (harmless). **The repo is created on first push:**
```bash
TOKEN=$(sed -n 's/^GITEA_API=//p' ~/dev/.env)
curl -s -X POST -H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"Arcade85","private":false,"default_branch":"main"}' \
https://git.kwalb.com/api/v1/user/repos
# then:
git push "https://kyle:$TOKEN@git.kwalb.com/kyle/Arcade85.git" main
```
API: `curl -H "Authorization: token $TOKEN" https://git.kwalb.com/api/v1/repos/kyle/Arcade85/…`
**Only commit/push when asked.** Stage only intended files. Never stage `*.p8` or
`*.env`.
### `.env` — do not `source` it
`~/dev/.env` holds `GITEA_URL`, `GITEA_API` (token), `GITEA_USERNAME`, `GITEA_EMAIL`
plus other service keys. **Do not `source` it** — a later line is a bare
`https://claude.ai/magic-link…` URL (not `key=value`) which breaks `source` in zsh.
Read values with sed:
```bash
TOKEN=$(sed -n 's/^GITEA_API=//p' ~/dev/.env)
```
## 5. `.gitignore` (already in place — don't remove)
`build/`, `DerivedData/`, `*.xcuserstate`, `xcuserdata/`, `*.moved-aside`, `*.hmap`,
`*.ipa`, `*.dSYM.zip`, `*.dSYM`, `.DS_Store`, `.build/`, `.swiftpm/`.
Add `*.p8` and `*.env` to this ignore list if/when they could appear here (none do
today, but the rule is: never commit signing keys or secret files).
## 6. Adding a game
1. Create `Games/<Name>/<Name>Scene.swift` + `<Name>Sim.swift` (mirror Dope Wars).
2. Add both files to the Xcode target in `Arcade85.xcodeproj/project.pbxproj`
(hand-maintained — there is **no** `project.yml`/xcodegen step; edit the pbxproj or
use Xcode's "Add Files to Arcade85").
3. Register the slot in `Shell/GameCatalog.swift`.
4. Build (simulator) to verify.